如何按定义顺序遍历类的属性?

10 投票
4 回答
7950 浏览
提问于 2025-04-15 19:23

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中也有作为例子)。

撰写回答