在继承时,确定哪个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
来检查属性的存在,假设最深的匹配是定义者。有更简单的方法吗?
答案 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
我不确定这种情况有一个简单的解决方法。