2016-09-16 30 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 

我不知道有一個這種情況下的簡單解決方法。