如何按定义顺序遍历类的属性?
Python 有一个非常实用的 dir()
函数,可以帮你列出一个类里面的内容。比如,对于这个类:
class C:
i = 1
a = 'b'
使用 dir(C)
会返回
['__doc__', '__module__', 'a', 'i']
这很好,但注意到 'a'
和 'i'
的顺序和它们定义时的顺序不一样了。
我想知道怎么才能按照定义的顺序遍历 C 类的属性(可能忽略掉内置的文档和模块属性)?对于上面的 C 类,顺序应该是 'i'
然后 'a'
。
补充说明: - 我正在写一些序列化/日志记录的代码,想要按照属性定义的顺序来序列化,这样输出的结果会和创建这个类的代码类似。
4 个回答
2
把这个方法放到你的类里面
def __setattr__(self, attr, value):
if attr not in dir(self):
if attr == "__ordered_fields__":
super.__setattr__(self, attr, value)
else:
if not hasattr(self, "__ordered_fields__"):
setattr(self, "__ordered_fields__", [])
self.__ordered_fields__.append(attr)
super.__setattr__(self, attr, value)
然后要按顺序获取字段,只需做类似下面的事情:
print(self.__ordered_fields__)
2
我刚开始学习Python,所以我的解决方案可能不是很有效。
class Q:
def __init__(self):
self.a = 5
self.b = 10
if __name__ == "__main__":
w = Q()
keys = w.__dict__.keys()
for k in keys:
print "Q.%s = %d"%(k,w.__dict__[k])
输出结果是:
Q.a = 5
Q.b = 10
8
我觉得在Python 2.x中这是不可能的。当类的成员传递给__new__
方法时,它们是以字典的形式提供的,所以这个时候顺序已经丢失了。因此,即使是元类也帮不了你(除非我遗漏了什么额外的特性)。
在Python 3中,你可以使用新的__prepare__
特殊方法来创建一个有序字典(这在PEP 3115中也有作为例子)。