[英]Using property method with setter prevents function from binding to object attribute
我試圖在此代碼中使用基於屬性的方法來控制類構造函數(在實例創建時篩選錯誤值)。 出於某種原因,我不明白函數set_sequence
在從@num.setter
方法調用時不會改變派生類 Binary 對象的屬性seq
- 它必須在其他地方調用。 我是否缺少有關屬性如何工作的基本知識?
class Number:
def __init__(self, num):
self.num = num
class Binary(Number):
def __init__(self, num):
super().__init__(num)
self.seq = ()
@property
def num(self):
return self._num
@num.setter
def num(self, value):
if value < 0:
raise ValueError('Unsigned numbers cannot be negative')
self._num = value
self.set_sequence() #this calls the function, but the value doesn't get bound
def set_sequence(self):
print('called ', end='')
self.seq = tuple([int(x) for x in bin(self.num)[2:]])
調用此代碼如下:
if __name__ == "__main__":
n1 = Binary(11)
print(f"{n1.num} = {n1.seq}")
n1.set_sequence()
print(f"{n1.num} = {n1.seq}")
給出:
called 11 = ()
called 11 = (1, 0, 1, 1)
當負值傳遞給構造函數時,這會按預期拋出異常,但我不明白為什么函數調用無法按預期運行。 順便提一下,此模式基於 Brett Slatkin 的 'Effective Python' 中的 Item#29,即在調用構造函數時使用 @property 進行類型檢查和值驗證的部分。
因為在調用@num.setter
super().__init__(num)
之后的構造函數中,您使用self.seq = ()
覆蓋存儲在 setter 方法中的值。
要獲得所需的輸出,您應該這樣做。 在您的示例中self.set_sequence()
被構造函數中的第二條指令覆蓋。
class Number:
def __init__(self, num):
self.num = num
class Binary(Number):
seq = ()
def __init__(self, num):
# or eventually here
# seq = ()
super().__init__(num)
@property
def num(self):
return self._num
@num.setter
def num(self, value):
if value < 0:
raise ValueError('Unsigned numbers cannot be negative')
self._num = value
self.set_sequence() #this calls the function, but the value doesn't get bound
def set_sequence(self):
print('called ', end='')
self.seq = tuple([int(x) for x in bin(self.num)[2:]])
if __name__ == "__main__":
n1 = Binary(11)
print(f"{n1.num} = {n1.seq}")
n1.set_sequence()
print(f"{n1.num} = {n1.seq}")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.