您的实施ALMOST工作。它的问题出现在destination.acc.set(source.acc.get())
。什么情况是,它首先查找destination.acc
,将设置_owner
到destination
,但它可以调用set()
之前,它必须解决的参数,source.acc.get()
,这最终会设置acc
的_owner
到source
。
由于destination.acc
和source.acc
是同一个对象(描述符存放的类,而不是实例),你是它的_owner
设置为source
后调用它set()
。这意味着你正在设置source._val
,而不是destination._val
。
,让你会直觉地想到行为的方式是摆脱或你的get()
和set()
与__get__()
和__set__()
取代他们,让您的描述符,可用于其原因是使用的描述符。
class Accessor(object):
def __get__(self, instance, owner): # you should use the conventional parameter names
if instance is None:
return self
else:
return instance._val
def __set__(self, instance, value):
instance._val = value
然后,你可以重写你的客户端代码
source = TestClass()
destination = TestClass()
source.acc = 'banana'
destination.acc = 'mango'
destination.acc = source.acc
print destination.acc
描述的重点是去除明确的getter和setter与看起来像简单的属性使用隐式调用者。如果你仍然想在Accessor
上使用你的getter和setter,那么不要把它作为描述符。做到这一点,而不是:
class Accessor(object):
def get(self):
if hasattr(self, '_val'):
return self._val
else:
return None
def set(self, val):
self._val = val
然后重写TestClass
看起来更像是这样的:
class TestClass(object):
def __init__(self):
self.acc = Accessor()
之后,你原来的客户端代码会工作。
谢谢。我正在使用Autodesk Maya中的PyMEL接口,我必须使用这种特定模式有两个原因:a)我知道基于__init __的方法,但是在__init__上实例化“接口”对象的执行速度要慢得多至少在Maya解释器中使用描述符。 b).get()/ .set()语法是一个PyMEL约定,我想坚持下去。我意识到它是非描述符的。 –
PyMEL系统中的现有类是否使用这样的描述符?还是他们使用“基于init”的方法?我发现很难相信,如果他们使用描述符,他们会维持这个惯例。 –
我有一些工作。我只需要到适当的键盘输入:)。这将是几个小时,因为我现在正准备上班。 –