亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

屬性的存取控制

之前也講過,Python 沒有真正意義上的私有屬性。然後這就導(dǎo)致了 Python 類別的封裝性比較差。我們有時會希望 Python 能夠定義私有屬性,然後提供公共可存取的 get 方法和 set 方法。 Python 其實可以透過魔術(shù)方法來實現(xiàn)封裝。

方法說明
#__getattr__(self, name)?此方法定義了你試圖存取一個不存在的屬性時的行為。因此,重載該方法可以實現(xiàn)捕獲錯誤拼寫然後進(jìn)行重定向, 或?qū)σ恍U棄的屬性進(jìn)行警告。
__setattr__(self, name, value)?定義了對屬性進(jìn)行賦值和修改操作時的行為。不管物件的某個屬性是否存在,都允許為該屬性進(jìn)行賦值.有一點需要注意,實現(xiàn)__setattr__ 時要避免"無限遞歸"的錯誤,
__delattr__(self , name)?__delattr__ 與__setattr__ 很像,只是它定義的是你刪除屬性時的行為。實作__delattr__ 是同時要避免"無限遞迴"的錯誤
__getattribute__(self, name)?__getattribute__ 定義了你的屬性被存取時的行為,相比較,__getattr__ 只有該屬性不存在時才會起作用。因此,在支援 __getattribute__ 的 Python 版本,呼叫__getattr__ 前必定會呼叫 __getattribute__``__getattribute__ 同樣要避免"無限遞歸"的錯誤。

?透過上面的方法表可以知道,在進(jìn)行屬性存取控制定義的時候你可能會很容易的引起一個錯誤,可以看看下面的範(fàn)例:

def __setattr__(self, name, value):
    self.name = value
    # 每當(dāng)屬性被賦值的時候, ``__setattr__()`` 會被調(diào)用,這樣就造成了遞歸調(diào)用。
    # 這意味這會調(diào)用 ``self.__setattr__('name', value)`` ,每次方法會調(diào)用自己。這樣會造成程序崩潰。
def __setattr__(self, name, value):
    # 給類中的屬性名分配值
    self.__dict__[name] = value  
    # 定制特有屬性

上面方法的呼叫具體範(fàn)例如下:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
class User(object):
    def __getattr__(self, name):
        print('調(diào)用了 __getattr__ 方法')
        return super(User, self).__getattr__(name)
    def __setattr__(self, name, value):
        print('調(diào)用了 __setattr__ 方法')
        return super(User, self).__setattr__(name, value)
    def __delattr__(self, name):
        print('調(diào)用了 __delattr__ 方法')
        return super(User, self).__delattr__(name)
    def __getattribute__(self, name):
        print('調(diào)用了 __getattribute__ 方法')
        return super(User, self).__getattribute__(name)
if __name__ == '__main__':
    user = User()
    # 設(shè)置屬性值,會調(diào)用 __setattr__
    user.attr1 = True
    # 屬性存在,只有__getattribute__調(diào)用
    user.attr1
    try:
        # 屬性不存在, 先調(diào)用__getattribute__, 后調(diào)用__getattr__
        user.attr2
    except AttributeError:
        pass
    # __delattr__調(diào)用
    del user.attr1

輸出的結(jié)果:

調(diào)用了 __setattr__ 方法
調(diào)用了 __getattribute__ 方法
調(diào)用了 __getattribute__ 方法
調(diào)用了 __getattr__ 方法
調(diào)用了 __delattr__ 方法
繼續(xù)學(xué)習(xí)
||
提交重置程式碼