簡體   English   中英

將屬性方法與 setter 一起使用可防止函數綁定到對象屬性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM