使对象的属性可迭代
我得到了一个包含多个属性的对象列表,像这样:
results = q.fetch(5)
for p in results:
print "%s %s, %d inches tall" % (p.first_name, p.last_name, p.height
我想知道是否可以遍历这些属性,这样我就可以像这样写 for x in p
。我想检查每个属性的值,但我不想写一大堆的IF语句。
4 个回答
1
要获取一个模型类的属性列表,可以调用 Model.properties()
(或者 instance.properties()
- 这是一个类方法)。这个方法会返回一个字典,字典里把属性名和属性类的实例对应起来;你可以通过 getattr(instance, name)
来获取这些属性的值。
如果你在使用 Expando
,还可以用 instance.dynamic_properties()
,这个方法会返回一个该对象上动态定义的属性列表。
3
你可以通过创建一个新的类来继承原来的变量类型,并定义你自己的iter(self)函数,这样就能实现你想要的效果。比如说,如果你想改变字典的遍历方式,可以这样做:
>>> class mydict(dict):
... def __iter__(self):
... for i in self.items():
... yield i
...
>>> x = mydict( {'a' : 1, 'b':2 } )
>>> for i in x:
... print i
...
('a', 1)
('b', 2)
6
我建议不要这样做。虽然有些特殊情况可能需要这样做,但大多数时候,避免这种 hack 的解决方案会更好。不过,如果你真的想这么做,可以使用 vars()
来获取一个属性的字典,然后遍历它。正如 @Nick 在下面提到的,App Engine 使用属性而不是直接的值来定义它的成员,所以你需要使用 getattr()
来获取它们的值。
results = q.fetch(5)
for p in results:
for attribute in vars(p).keys()
print '%s = %s' % (attribute, str(getattr(p, attribute)))
下面演示了 vars()
的作用:
>>> class A:
... def __init__(self, a, b):
... self.a = a
... self.b = b
...
>>> a = A(1, 2)
>>> vars(a)
{'a': 1, 'b': 2}
>>> for attribute in vars(a).keys():
... print '%s = %s' % (attribute, str(getattr(a, attribute)))
...
a = 1
b = 2