关于反射:如何访问Python超类的属性,例如

How to access properties of Python super classes e.g. via __class__.__dict__?

如何获取Python类的所有属性名,包括从超级类继承的那些属性?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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__', ), ('x', <property object at 0x114bba8>), ('__weakref__', ), ('__doc__', None)]
b.__class__.__dict__.items()
[('y', 10), ('__module__', '__main__'), ('__doc__', None)]

如何通过B访问A的属性?需要:"给我一份从B继承的所有财产名称的清单,包括从A继承的财产名称!"

1
2
3
4
>>> [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。


您可以使用dir()

1
2
3
4
for attr_name in dir(B):
    attr = getattr(B, attr_name)
    if isinstance(attr, property):
        print attr


您可以使用"dir",也可以遵循由"mro"(方法解析顺序,由类上的__mro__属性给出)返回的元组中包含的所有类-此后面的方法是发现属性的唯一方法,这些属性稍后被子类覆盖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> 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)
>>>