您的實施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」的方法?我發現很難相信,如果他們使用描述符,他們會維持這個慣例。 –
我有一些工作。我只需要到適當的鍵盤輸入:)。這將是幾個小時,因爲我現在正準備上班。 –