【问题标题】:In a Python object, how can I see a list of properties that have been defined with the @property decorator?在 Python 对象中,如何查看已使用 @property 装饰器定义的属性列表?
【发布时间】:2011-08-18 01:50:58
【问题描述】:

我可以使用self.__dict__ 查看一流的成员变量,但我还希望查看使用@property 装饰器定义的属性字典。我该怎么做?

【问题讨论】:

    标签: python python-2.6 python-2.7


    【解决方案1】:

    你可以在你的类中添加一个看起来像这样的函数:

    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))
    

    这会查找类中的任何属性,然后创建一个字典,其中包含具有当前实例值的每个属性的条目。

    【讨论】:

    • 请注意,这仅列出在类本身 IIRC 上声明的属性。不会列出超类的属性。
    • 你可以走 self.__class__.mro() 找到父类。
    • 单行是return {k: getattr(self, k) for k, v in self.__class__.__dict__.iteritems() if isinstance(v, property)}
    【解决方案2】:

    属性是类的一部分,而不是实例。因此,您需要查看self.__class__.__dict__ 或等效的vars(type(self))

    所以属性是

    [k for k, v in vars(type(self)).items() if isinstance(v, property)]
    

    【讨论】:

      【解决方案3】:

      对于一个对象 f,这给出了作为属性的成员列表:

      [n for n in dir(f) if isinstance(getattr(f.__class__, n), property)]
      

      【讨论】:

        【解决方案4】:

        正如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__ 可能会重复访问一些祖先。
        • 这里也指出了这一点:stackoverflow.com/questions/5876049/…
        • @user2357112supportsMonica 啊,是的。你说的对。我相应地更新了答案。谢谢。
        【解决方案5】:

        dir(obj) 给出了obj 的所有属性的列表,包括方法和属性。

        【讨论】:

        • 对,但我需要具体了解属性。我考虑覆盖 @property 装饰器以将它们添加到 obj 上的注册表中,但我认为 Python 可能有一个花哨的 __something__ 已经这样做了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 2014-06-21
        • 2014-09-09
        • 1970-01-01
        • 2014-10-17
        相关资源
        最近更新 更多