如何获取已定义的类属性(不包括魔术方法/属性)的字典?

时间:2019-03-15 18:32:45

标签: python python-2.7 class

基本上,我在做什么

class A(object):
    a = 1
    b = 2

copy.deepcopy(dict(A.__dict__))

出现错误

  

TypeError:对象。(getset_descriptor)不安全,请使用getset_descriptor。()

如果我更新下面的代码,然后从类词典项目中弹出 __ dict __ __ weakref __

class A(object):
    a = 1
    b = 2

attrs = dict(A.__dict__)
attrs.pop("__weakref__")
attrs.pop("__dict__")
copy.deepcopy(dict(A.__dict__))
# It gives {'__module__': '__main__', 'a': 1, 'b': 2, '__doc__': None}

工作正常,我了解这与复制 weakref 有关,这是错误的。

在不需要专门弹出 __ dict __ __ weakref __的地方,还有什么更好的方法可以做到,而我只能得到属性< / strong>,不包括魔术方法/属性?

1 个答案:

答案 0 :(得分:0)

在Python中并不是真的那么简单,因为通常没有任何方法可以知道什么是“内置”的,什么不是。另外,如果您想获得继承的属性,则使用__dict__是不够的。为此,您需要使用dir来代替,它可以方便地处理与实例本身相同的对象实例,因此用途更广泛。

最简单的通用解决方案是为自己定义一个简单的小函数,该函数根据“属性”封装所需的内容。然后,您可以显式删除您不想保留的属性(不过,请注意,如果您深度复制了此类过滤对象,则可能不再有可用的Python对象):

In [1]: {k: getattr(A, k) for k in set(dir(A)) - set(dir(object)) - {'__weakref__', '__dict__', '__module__'}}
Out[1]: {'b': 2, 'a': 1}

In [2]: class B(A):
    ...:     c = 10

In [3]: {k: getattr(B, k) for k in set(dir(B)) - set(dir(object)) - {'__weakref__', '__dict__', '__module__'}}
Out[3]: {'b': 2, 'c': 10, 'a': 1}