如何访问 Python 超类的属性,例如通过 __class__.__dict__?
Posted
技术标签:
【中文标题】如何访问 Python 超类的属性,例如通过 __class__.__dict__?【英文标题】:How to access properties of Python super classes e.g. via __class__.__dict__? 【发布时间】:2012-03-11 18:41:25 【问题描述】:如何获取 python 类的所有属性名称包括从超类继承的那些属性?
class A(object):
def getX(self):
return "X"
x = property(getX)
a = A()
a.x
'X'
class B(A):
y = 10
b = B()
b.x
'X'
a.__class__.__dict__.items()
[('__module__', '__main__'), ('getX', <function getX at 0xf05500>), ('__dict__', <attribute '__dict__' of 'A' objects>), ('x', <property object at 0x114bba8>), ('__weakref__', <attribute '__weakref__' of 'A' objects>), ('__doc__', None)]
b.__class__.__dict__.items()
[('y', 10), ('__module__', '__main__'), ('__doc__', None)]
如何通过 b 访问 a 的属性? 需要:“给我一份来自 b 的所有 属性 名称的列表,包括从 a 继承的那些!”
>>> [q for q in a.__class__.__dict__.items() if type(q[1]) == property]
[('x', <property object at 0x114bba8>)]
>>> [q for q in b.__class__.__dict__.items() if type(q[1]) == property]
[]
当使用第二个 (b) 时,我想从第一个 (a) 中获取结果,但当前只能得到一个空列表。这也应该适用于从 B 继承的另一个 C。
【问题讨论】:
请注意,y
不是属性,它只是一个整数。你想要所有可能不是函数的类变量吗?
如果你关心 Python 风格(PEP 8),或者如果你不需要能够做函数调用版本(你会如果你通过super()
---super(...).x = 'Y'
设置属性会失败),只需使用property
作为装饰器,如@property
,def x(self): return 'X'
。
感谢这些 cmets。我试图创建一个简单的示例而不是我的复杂代码,是的,因此我没有考虑 PEP8。我不关心y
,因为我只需要属性。
重复***.com/questions/8529192/…
【参考方案1】:
你可以使用dir()
:
for attr_name in dir(B):
attr = getattr(B, attr_name)
if isinstance(attr, property):
print attr
【讨论】:
好的,我想这对我有用,最后是print attr_name, attr.__get__(b)
。谢谢。
感谢#python.de@irc.freenode.net 上的帮助,提供导致替代答案的提示:for c in b.__class__.__mro__: if issubclass(c, A): for p in [q for q in c.__dict__.items() if type(q[1]) == property]: print p[0], '=', p[1].__get__(b)
@user1156548:我认为没有必要自己走 MRO。你当然可以,但为什么应该你呢?
使用 mro 的工作方式与上述 dir() 解决方案类似。没有这两者它是行不通的,因为 class.__dict__ 不包含超类的属性。你有什么建议@sven-marnach
@user1156548:我建议使用dir()
,因为它更容易并且不会显示已被子类覆盖的属性——我猜你不希望它们出现两次。跨度>
【参考方案2】:
您可以使用“dir”,也可以遵循“mro”返回的元组中包含的所有类(方法解析顺序,由类上的__mro__
属性给出) - 后一种方法是发现后来被子类覆盖的属性的唯一方法:
>>> class A(object):
... b = 0
...
>>> class B(A):
... b = 1
...
>>> for cls in B.__mro__:
... for item in cls.__dict__.items():
... if item[0][:2] != "__":
... print cls.__name__, item
...
B ('b', 1)
A ('b', 0)
>>>
【讨论】:
以上是关于如何访问 Python 超类的属性,例如通过 __class__.__dict__?的主要内容,如果未能解决你的问题,请参考以下文章