2
所以我今天在我的代碼中遇到了這個討厭的bug。我最近剛剛使用Python屬性,並且在屬性更新時使用它來保存另一個變量中舊屬性的值。因此,當調用setter函數時,我需要保存舊值,然後再傳輸新值。這是一個錯誤? Python屬性無法正常工作+ =
事實證明,當在一個屬性上使用+=
時,__iadd__
方法被調用,在原地更新屬性,然後調用setter。但到那個時候,舊的價值就失去了。以下是說明問題的一些代碼。
class Container(object):
def __init__(self, val):
self.val = val
def __add__(self, other):
print('in __add__', other)
return Container(self.val + other.val)
def __iadd__(self, other):
print('in __iadd__:', other)
self.val += other.val
return self
def __str__(self):
return str(self.val)
class Test:
def __init__(self):
self._val = Container(0)
@property
def val(self):
return self._val
@val.setter
def val(self, values):
print("changing from {} to {}".format(self._val, values))
self._val = values
test = Test()
print('val=', test.val)
test.val = Container(2)
print('val=', test.val)
test.val = test.val + Container(1)
print('val=', test.val)
test.val += Container(1)
print('val=', test.val)
test.val.__iadd__(Container(1))
print('val=', test.val)
運行時,它提供這樣的結果:
val= 0
changing from 0 to 2
val= 2
in __add__ 1
changing from 2 to 3
val= 3
in __iadd__: 1
changing from 4 to 4
val= 4
in __iadd__: 1
val= 5
它說,它正在改變4比4,但它真的改變3至4和被錯過。所以我想知道如果這是一個錯誤,我錯過了一些東西,或者我只是不應該使用+ =,如果我正在處理一個屬性並需要舊值。
你可能想看看http://stackoverflow.com/questions/11987949/how-to-implement-iadd-for-a -python-property – Jan
這幾乎有幫助。如果我在對象上用__add__替換了__iadd__,那麼它會修復它。但只是我的運氣'__Iadd__'是numpy數組的一個ready-only屬性。所以我剛剛擺脫了setter,並使其成爲一個非屬性集函數。 – TheLoneMilkMan