【发布时间】:2011-08-18 01:50:58
【问题描述】:
我可以使用self.__dict__ 查看一流的成员变量,但我还希望查看使用@property 装饰器定义的属性字典。我该怎么做?
【问题讨论】:
标签: python python-2.6 python-2.7
我可以使用self.__dict__ 查看一流的成员变量,但我还希望查看使用@property 装饰器定义的属性字典。我该怎么做?
【问题讨论】:
标签: python python-2.6 python-2.7
你可以在你的类中添加一个看起来像这样的函数:
def properties(self):
class_items = self.__class__.__dict__.iteritems()
return dict((k, getattr(self, k))
for k, v in class_items
if isinstance(v, property))
这会查找类中的任何属性,然后创建一个字典,其中包含具有当前实例值的每个属性的条目。
【讨论】:
return {k: getattr(self, k) for k, v in self.__class__.__dict__.iteritems() if isinstance(v, property)}
属性是类的一部分,而不是实例。因此,您需要查看self.__class__.__dict__ 或等效的vars(type(self))
所以属性是
[k for k, v in vars(type(self)).items() if isinstance(v, property)]
【讨论】:
对于一个对象 f,这给出了作为属性的成员列表:
[n for n in dir(f) if isinstance(getattr(f.__class__, n), property)]
【讨论】:
正如user2357112-supports-monica 在对duplicate question 的评论中指出的那样,接受的答案只获得直接在类上定义的那些属性,缺少继承的属性。为了解决这个问题,我们还需要遍历父类:
from typing import List
def own_properties(cls: type) -> List[str]:
return [
key
for key, value in cls.__dict__.items()
if isinstance(value, property)
]
def properties(cls: type) -> List[str]:
props = []
for kls in cls.mro():
props += own_properties(kls)
return props
例如:
class GrandparentClass:
@property
def grandparent_prop(self):
return "grandparent_prop"
class ParentClass(GrandparentClass):
@property
def parent_prop(self):
return "parent"
class ChildClass(ParentClass):
@property
def child_prop(self):
return "child"
properties(ChildClass) # ['child_prop', 'parent_prop', 'grandparent_prop']
如果您需要获取实例的属性,只需将instance.__class__ 传递给get_properties
【讨论】:
cls.__mro__ 而不是递归cls.__bases__,以正确处理菱形继承。递归cls.__bases__ 可能会重复访问一些祖先。
dir(obj) 给出了obj 的所有属性的列表,包括方法和属性。
【讨论】:
@property 装饰器以将它们添加到 obj 上的注册表中,但我认为 Python 可能有一个花哨的 __something__ 已经这样做了。