如何确定继承时哪个Python类提供属性

时间:2016-09-16 17:08:20

标签: python inheritance

在继承时,确定哪个Python类定义属性的最简单方法是什么?例如,说我有:

class A(object):

    defined_in_A = 123

class B(A):
    pass

a = A()
b = B()

我希望此代码通过:

assert hasattr(a, 'defined_in_A')
assert hasattr(A, 'defined_in_A')
assert hasattr(b, 'defined_in_A')
assert hasattr(B, 'defined_in_A')

assert defines_attribute(A, 'defined_in_A')
assert not defines_attribute(B, 'defined_in_A')

我如何实现虚构的defines_attribute函数?我的第一个想法是遍历整个继承链,并使用hasattr来检查属性的存在,假设最深的匹配是定义者。有更简单的方法吗?

1 个答案:

答案 0 :(得分:2)

(几乎)每个python对象都使用它自己的实例变量(我们通常称为类变量的类对象的实例变量)定义,以将其作为字典,您可以使用vars函数并检查其成员身份它:

>>> "defined_in_A" in vars(A)
True
>>> "defined_in_A" in vars(B)
False
>>> "defined_in_A" in vars(a) or "defined_in_A" in vars(b)
False

这个问题是当一个类使用__slots__或内置对象时它不起作用,因为它改变了实例变量的存储方式:

class A(object):
    __slots__ = ("x","y")
    defined_in_A = 123

>>> A.x
<member 'x' of 'A' objects>
>>> "x" in vars(a)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    "x" in vars(a)
TypeError: vars() argument must have __dict__ attribute
>>> vars(1) #or floats or strings will raise the same error
Traceback (most recent call last):
   ...
TypeError: vars() argument must have __dict__ attribute

我不确定这种情况有一个简单的解决方法。