2016-09-16 69 views
3

确定哪个Python类在继承时定义属性的最简单方法是什么?例如,假设我有:如何确定哪个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

这是什么实际使用情况? – jonrsharpe

+0

'if'defined_in_A'not in vars(B)'可能就是你正在寻找的东西,只检查在该对象上定义的实例变量而不检查它的基数或类型。 –

回答

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 

我不知道有一个这种情况下的简单解决方法。