如何按照定义的顺序迭代类的属性?

时间:2010-02-17 13:28:48

标签: python reflection

Python附带了方便的dir()函数,可以为您列出类的内容。例如,对于这个类:

class C:
   i = 1
   a = 'b'

dir(C)会返回

['__doc__', '__module__', 'a', 'i']

这很好,但请注意'a''i'的顺序现在与定义它们的顺序不同。

如何按照定义的顺序迭代C的属性(可能忽略内置的doc& module属性)?对于上面的C类,将是'i'然后'a'

附录: - 我正在编写一些序列化/日志记录代码,我想按照它们定义的顺序序列化属性,以便输出类似于创建类的代码。

4 个答案:

答案 0 :(得分:8)

我不认为这在Python 2.x中是可行的。当类成员被提供给__new__方法时,它们被作为字典给出,因此在那时订单已经丢失。因此,即使是元类也无法帮助你(除非我错过了其他功能)。

在Python 3中,您可以使用新的__prepare__特殊方法创建有序字典(这甚至在PEP 3115中作为示例提供)。

答案 1 :(得分: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

答案 2 :(得分: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__)

答案 3 :(得分:1)

此信息无法访问,因为属性存储在dict中,这本身就是无序的。 Python不会在任何地方存储有关订单的信息。

如果您希望序列化格式按特定顺序存储内容,则明确指定 顺序。你不会使用包含你不知道或不关心的事物的dir,你会明确地提供一个描述序列化内容的列表(或其他)。