在此示例代码中,我想确定 x
是否是 TestProperty
的实例:
class TestProperty(object):
def __init__(self, name):
self._name = name
def __get__(self, instance, cls):
return getattr(instance, self._name)
def __set_(self, instance, value):
setattr(instance, self._name, value)
class Test(object):
x = TestProperty("x")
print isinstance(Test.x, TestProperty)
但是,我遇到以下异常:
Traceback (most recent call last):
File "/home/zenoss/testproperties.py", line 14, in <module>
print isinstance(Test.x, TestProperty)
File "/home/zenoss/testproperties.py", line 6, in __get__
return getattr(instance, self._name)
AttributeError: 'NoneType' object has no attribute 'x'
当属性是描述符时,是否有办法判断它是否是类的实例?
最佳答案
使用当前的__get__
,Test.x
会导致AttributeError
,因为当代码使用类、instance<访问描述符时
被传递None
; (=> getattr(None, 'x')
=> None.x
)
您应该修改__get__
来处理这种情况:
>>> class TestProperty(object):
... def __init__(self, name):
... self._name = name
... def __get__(self, instance, cls):
... if instance is None: # To handle access through class, not instance
... return self # returns the TestProperty instance itself.
... return getattr(instance, self._name)
... def __set_(self, instance, value):
... setattr(instance, self._name, value)
...
>>> class Test(object):
... x = TestProperty("x")
...
>>> isinstance(Test.x, TestProperty)
True
<小时/>
顺便说一句,您可能知道,使用 x = TestProperty("x")
,通过实例访问 x
属性将导致另一个异常,因为它将调用__get__
(-> getattr(..) -> __get__ -> getattr(..) -> ...) 递归直到堆栈溢出。
关于python - 如何确定描述符的类别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42676527/