파이썬에서 객체 속성을 반복
몇 가지 속성과 메소드가있는 파이썬 객체가 있습니다. 객체 속성을 반복하고 싶습니다.
class my_python_obj(object):
attr1='a'
attr2='b'
attr3='c'
def method1(self, etc, etc):
#Statements
모든 객체 속성과 현재 값을 포함하는 사전을 생성하고 싶지만 동적 방식으로 수행하고 싶습니다 (따라서 나중에 다른 속성을 추가하면 함수를 업데이트해야한다는 것을 기억할 필요가 없습니다).
PHP에서 변수는 키로 사용할 수 있지만 파이썬의 객체는 설명 할 수 없으며 점 표기법을 사용하면 내 var의 이름으로 새 속성이 만들어집니다.
더 명확하게하기 위해 :
def to_dict(self):
'''this is what I already have'''
d={}
d["attr1"]= self.attr1
d["attr2"]= self.attr2
d["attr3"]= self.attr3
return d
·
def to_dict(self):
'''this is what I want to do'''
d={}
for v in my_python_obj.attributes:
d[v] = self.v
return d
업데이트 : 속성을 사용하면 메서드가 아닌이 객체의 변수 만 의미합니다.
다음과 같은 수업이 있다고 가정
>>> class Cls(object):
... foo = 1
... bar = 'hello'
... def func(self):
... return 'call me'
...
>>> obj = Cls()
dir
객체를 호출 하면 파이썬 특수 속성을 포함하여 해당 객체의 모든 속성이 반환됩니다. 메소드와 같은 일부 오브젝트 속성을 호출 할 수 있지만
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo', 'func']
목록 이해를 사용하여 항상 특수한 방법을 필터링 할 수 있습니다.
>>> [a for a in dir(obj) if not a.startswith('__')]
['bar', 'foo', 'func']
또는지도 / 필터를 선호하는 경우
>>> filter(lambda a: not a.startswith('__'), dir(obj))
['bar', 'foo', 'func']
메소드를 필터링하려면 내장 callable
을 검사로 사용할 수 있습니다 .
>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj,a))]
['bar', 'foo']
당신은 또한 사용하여 클래스와 부모의 차이점을 검사 할 수 있습니다.
>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])
일반적으로 클래스에__iter__
메소드를 넣고 객체 속성을 반복하거나이 믹스 인 클래스를 클래스에 넣습니다.
class IterMixin(object):
def __iter__(self):
for attr, value in self.__dict__.iteritems():
yield attr, value
수업 :
>>> class YourClass(IterMixin): pass
...
>>> yc = YourClass()
>>> yc.one = range(15)
>>> yc.two = 'test'
>>> dict(yc)
{'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'}
Objects in python store their atributes (including functions) in a dict called __dict__
. You can (but generally shouldn't) use this to access the attributes directly. If you just want a list, you can also call dir(obj)
, which returns an iterable with all the attribute names, which you could then pass to getattr
.
However, needing to do anything with the names of the variables is usually bad design. Why not keep them in a collection?
class Foo(object):
def __init__(self, **values):
self.special_values = values
You can then iterate over the keys with for key in obj.special_values:
The correct answer to this is that you shouldn't. If you want this type of thing either just use a dict, or you'll need to explicitly add attributes to some container. You can automate that by learning about decorators.
In particular, by the way, method1 in your example is just as good of an attribute.
class someclass:
x=1
y=2
z=3
def __init__(self):
self.current_idx = 0
self.items = ["x","y","z"]
def next(self):
if self.current_idx < len(self.items):
self.current_idx += 1
k = self.items[self.current_idx-1]
return (k,getattr(self,k))
else:
raise StopIteration
def __iter__(self):
return self
then just call it as an iterable
s=someclass()
for k,v in s:
print k,"=",v
As mentioned in some of the answers/comments already, Python objects already store a dictionary of their attributes (methods aren't included). This can be accessed as __dict__
, but the better way is to use vars
(the output is the same, though). Note that modifying this dictionary will modify the attributes on the instance! This can be useful, but also means you should be careful with how you use this dictionary. Here's a quick example:
class A():
def __init__(self, x=3, y=2, z=5):
self.x = x
self._y = y
self.__z__ = z
def f(self):
pass
a = A()
print(vars(a))
# {'x': 3, '_y': 2, '__z__': 5}
# all of the attributes of `a` but no methods!
# note how the dictionary is always up-to-date
a.x = 10
print(vars(a))
# {'x': 10, '_y': 2, '__z__': 5}
# modifying the dictionary modifies the instance attribute
vars(a)["_y"] = 20
print(vars(a))
# {'x': 10, '_y': 20, '__z__': 5}
Using dir(a)
is an odd, if not outright bad, approach to this problem. It's good if you really needed to iterate over all attributes and methods of the class (including the special methods like __init__
). However, this doesn't seem to be what you want, and even the accepted answer goes about this poorly by applying some brittle filtering to try to remove methods and leave just the attributes; you can see how this would fail for the class A
defined above.
(using __dict__
has been done in a couple of answers, but they all define unnecessary methods instead of using it directly. Only a comment suggests to use vars
).
For python 3.6
class SomeClass:
def attr_list(self, should_print=False):
items = self.__dict__.items()
if should_print:
[print(f"attribute: {k} value: {v}") for k, v in items]
return items
For python 3.6
class SomeClass:
def attr_list1(self, should_print=False):
for k in self.__dict__.keys():
v = self.__dict__.__getitem__(k)
if should_print:
print(f"attr: {k} value: {v}")
def attr_list(self, should_print=False):
b = [(k, v) for k, v in self.__dict__.items()]
if should_print:
[print(f"attr: {a[0]} value: {a[1]}") for a in b]
return b
참고URL : https://stackoverflow.com/questions/11637293/iterate-over-object-attributes-in-python
'Programing' 카테고리의 다른 글
왜 std :: move std :: shared_ptr을 사용합니까? (0) | 2020.07.03 |
---|---|
TreeMap을 반복하는 방법? (0) | 2020.07.02 |
텍스트 상자에 자리 표시 자 텍스트 추가 (0) | 2020.07.02 |
node.js에서 객체 키를 반복 (0) | 2020.07.02 |
SQL Server 연결 문자열에서 포트 번호를 지정하는 방법은 무엇입니까? (0) | 2020.07.02 |