为什么在__init__函数中声明描述符类会破坏描述符功能?
在下面的B类中,我希望每当给().a赋值时,能够调用A类中的__set__
函数。然而,实际上给().a赋值时,它只是直接用新值覆盖了().a。而C类中的
class A(object):
def __set__(self, instance, value):
print "__set__ called: ", value
class B(object):
def __init__(self):
self.a = A()
class C(object):
a = A()
def test1( class_in ):
o = class_in()
o.a = "test"
if isinstance(o.a, A):
print "pass"
else:
print "fail"
def test2( class_in ):
o1, o2 = class_in(), class_in()
if o1.a is o2.a:
print "fail"
else:
print "pass"
3 个回答
0
我遇到了一个类似的问题,我想用一个描述符来管理对象的属性。结果我发现,这些属性在所有对象中都被覆盖了,导致它们不再是独立的。
我在StackOverflow上提了个问题,得到的答案可以在这里找到:类属性无缘无故改变值
关于描述符的一个很好的文档链接在这里:http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/
下面是来自上述链接的一个描述符示例:
class Numberise(object):
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
if self.name not in instance.__dict__:
raise (AttributeError, self.name)
return '%o'%(instance.__dict__[self.name])
def __set__(self, instance, value):
print ('setting value to: %d'%value)
instance.__dict__[self.name] = value
0
这里有一个类,它可以通过最初的测试,但在大多数情况下不要尝试使用它。因为它在检查自己类型的时候会失败!
class E(object):
def __new__(cls, state):
class E(object):
a = A(state)
def __init__(self, state):
self.state = state
return E(state)
#>>> isinstance(E(1), E)
#False
5
根据文档的说明:
以下方法仅适用于当包含该方法的类的实例(也就是所谓的描述符类)出现在另一个新式类的类字典中,这个新式类被称为拥有类。在下面的例子中,“属性”指的是拥有类的
__dict__
中,属性名称对应的键。描述符只能作为新式类本身来实现。
所以,你不能在实例上使用描述符。
不过,由于描述符可以获取到用于访问它的实例的引用,你可以把这个实例作为存储状态的关键,这样就可以根据不同的实例实现不同的行为。