【问题标题】:List all python3 class properties列出所有 python3 类属性
【发布时间】:2021-10-16 13:10:06
【问题描述】:

编辑:以下方法在使用类时有效,但在使用实例时无效。它们也在 Python3 中工作。

class A:
    @property
    def p(self):
        return ""

>>> a = A()
>>> vars(a)
{}
>>> vars(A)
{'p': <property object at 0x0000000000000000>, '__module__': '__main__', '__doc__': None}
>>>

================================================ ===

我正在寻找一种方法来列出在 python3 的类中使用 @property 装饰器定义的所有属性(以及仅这些属性)。

在 python2 中,您可以使用 vars 并获取作为 property 类实例的所有属性(如许多以前的答案中所述),但在 python3 中它不能以这种方式工作,vars不返回属性。使用__dict__ 与使用vars 相同。

使用dir()返回所有属性,并且不让区分属性和其他属性。

另外,访问属性时,有返回值的类型,不是property的实例。

我的最终目标是定义我自己的属性类型(通过继承property),并列出每种类型的属性。

【问题讨论】:

  • instance.__dict__ 返回所有属性,但不返回类型。
  • 你能举个例子吗?
  • @JacopoBonomi 使用 __dict__ 与使用 vars 相同。它不返回使用 @property 装饰器定义的属性

标签: python python-3.x properties


【解决方案1】:

列出类的所有属性实例的可能性:

dir 方式

class A():
    def __init__(self): pass
    @property
    def c(self): return self._c
    @c.setter
    def c(self, v): self._c = v

    @property
    def d(self): return self._c
    @c.setter
    def d(self, v): self._c = v

props =  = filter(lambda attr: isinstance(v, property), [getattr(A, i) for i in dir(A)])

print(list(props))

输出

[<property object at 0x7fee3a1470e0>, <property object at 0x7fee3a147130>]

__dict__way

props = {k: v for k, v in A.__dict__.items() if isinstance(v, property)}
print(list(props))

输出

{'c': <property object at 0x7efd84c21090>, 'd': <property object at 0x7efd84c210e0>}

__dict__way 的优点是保持对属性标识符的引用

【讨论】:

  • 我不清楚“另外”部分。一个例子会很有用
  • 看来您需要将vars 与类一起使用,而不是类的实例,这对我不起作用。谢谢!
  • 根据上述评论编辑答案
  • 我看到了——在编辑后投了赞成票 :)
  • 请注意 vars__dict__ 给出相同的结果 - 应将其添加到答案中
【解决方案2】:

这是交互式 REPL 中的一个示例,将演示如何执行此操作:

>>> class Foo:
...   @property
...   def bar(self):
...     return self
...     
>>> f = Foo()
>>> f.bar
<__main__.Foo object at 0x11b197828>
>>> Foo.bar
<property object at 0x11b677548>
>>> f.__class__.__dict__['bar']
<property object at 0x11b677548>
>>> vars(f)
{}
>>> vars(Foo)
mappingproxy({'__module__': '__main__', 'bar': <property object at 0x11b677548>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None})
>>> vars(Foo) == Foo.__dict__
True
>>> type(f) is f.__class__ is Foo
True
>>> {k:v for k, v in vars(Foo).items() if isinstance(v, property)}
{'bar': <property object at 0x11b677548>}
>>> {k:v for k, v in vars(type(f)).items() if isinstance(v, property)}
{'bar': <property object at 0x11b677548>}
>>> dir(Foo)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar']
>>> dir(f)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar']
>>> [d for d in dir(f) if isinstance(getattr(f, d), property)]
[]
>>> [d for d in dir(Foo) if isinstance(getattr(Foo, d), property)]
['bar']

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2016-07-06
    相关资源
    最近更新 更多