簡體   English   中英

Python的屬性裝飾器不能按預期工作

[英]Python's property decorator does not work as expected

class Silly:
    @property
    def silly(self):
        "This is a silly property"
        print("You are getting silly")
        return self._silly

    @silly.setter
    def silly(self, value):
        print("You are making silly {}".format(value))
        self._silly = value

    @silly.deleter
    def silly(self):
        print("Whoah, you killed silly!")
        del self._silly

s = Silly()
s.silly = "funny"
value = s.silly
del s.silly

但它沒有打印出“你變得愚蠢”,“你正在制造愚蠢的搞笑”,......正如預期的那樣。 不知道為什么。 親愛的,你能讓我弄清楚嗎?

提前致謝!

property裝飾器僅適用於新式類另請參見 )。 Make Silly明確地從object擴展,使其成為一個新式的類。 (在Python 3中,所有類都是新式類)

class Silly(object):
    @property
    def silly(self):
        # ...
    # ...

您很可能知道添加屬性的正確方法是使用:

@property
def silly(self):
    return self._silly


@silly.setter:
def silly(self, value):
    self._silly = value

但是這需要新的樣式類,即鏈中的某個地方應該是一個class ParentClass(object): 使用silly = property(get_silly, set_silly)的類似選項具有相同的要求。

但是,還有另一種選擇,即使用相應的私有變量,如self._silly ,並覆蓋__getattr____setattr__方法:

def __getattr__(self, name): 
    """Called _after_ looking in the normal places for name."""  

    if name == 'silly':
        self._silly
    else:
        raise AttributeError(name)


def __setattr__(self, name, value):
    """Called _before_ looking in the normal places for name."""
    if name == 'silly':
        self.__dict__['_silly'] = value
    else:
        self.__dict__[name] = value

注意檢查其他屬性如何調用__getattr__ ,但檢查其他屬性之前調用__setattr__ 因此,如果不是可接受的屬性,前者可以而且應該引發錯誤,后者應該設置屬性。 不要使用self._silly = value__setattr__因為這將導致無限遞歸。

另請注意,由於我們在這里處理舊樣式類,您實際上應該使用dict方法,而不是更新的baseclass.__setattr__(self, attr, value) ,請參閱docs 如果你需要,也會存在類似的__delattr__()

使用此代碼,您現在可以執行以下操作:

i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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