在Python中迭代对象的属性

我有一个python对象有几个属性和方法。 我想迭代对象的属性。

class my_python_obj(object): attr1='a' attr2='b' attr3='c' def method1(self, etc, etc): #Statements 

我想生成一个包含所有对象属性及其当前值的字典,但我想以dynamic的方式来做(所以如果以后我添加另一个属性,我不必记得更新我的函数)。

在PHPvariables可以用作键,但python中的对象是unsuscriptable,如果我使用点符号为此它创build一个新的属性与我的变种的名称,这不是我的意图。

只是为了使事情更清楚:

 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 

更新:有了属性,我的意思是只有这个对象的variables,而不是方法。

假设你有一个类如

 >>> class Cls(object): ... foo = 1 ... bar = 'hello' ... def func(self): ... return 'call me' ... >>> obj = Cls() 

在对象上调用dir会返回该对象的所有属性,包括python特殊属性。 尽pipe某些对象属性是可调用的,例如方法。

 >>> 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。

 >>> 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__方法,遍历对象的属性,或者把这个mixin类放到你的类中。

 class IterMixin(object): def __iter__(self): for attr, value in self.__dict__.iteritems(): yield attr, value 

你的class:

 >>> 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'} 

python中的对象将它们的属性(包括函数)存储在一个名为__dict__的字典中。 你可以(但通常不应该)使用它直接访问属性。 如果你只是想要一个列表,你也可以调用dir(obj) ,它返回一个包含所有属性名称的iterable,然后你可以传递给getattr

但是,需要对variables名称做任何事情通常都是不好的devise。 为什么不把它们保存在一个集合?

 class Foo(object): def __init__(self, **values): self.special_values = values 

然后,您可以使用for key in obj.special_values:的键来遍历键for key in obj.special_values:

 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 

那么就把它叫做迭代器吧

 s=someclass() for k,v in s: print k,"=",v 

正确的答案是,你不应该。 如果你想要这种types的东西或者只是使用一个字典,或者你需要显式地添加属性到一些容器。 你可以通过学习装饰器来自动化。

特别是顺便说一下,在你的例子中,method1和属性一样好。