Python魔術方法 __getattr__、__getattribute__使用詳解

浪裡小白羊發表於2017-12-27

Python魔術方法 getattr、__getattribute__使用詳解

  • _getattr_(self,attr)
    • 觸發時機:獲取不存在的物件成員時觸發
    • 引數:1、接收當前物件的self,2、獲取成員名稱的字串
    • 返回值: 必須有值
    • 作用:為訪問不存在的屬性設定值
    • 注意:_getattribute_()無論何時都會在_getattr_()之前觸發,觸發了_getattribute_()有返回值就不會在觸發_getattr_()了
  • _getattribute_(self,attr)
    • 觸發時機:使用物件成員時觸發,無論成員是否存在
    • 引數:1、接收當前物件的self,2、獲取成員名稱的字串
    • 返回值: 必須有值
    • 作用:在具有封裝操作(私有化時),為程式開部分訪問許可權使用
class Human:
    # 成員屬性
    name = None
    sex = None
    age = None
    
    # 成員方法
    # 物件初始化
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    # 訪問不存在成員時觸發
    def __getattr__(self,attr):
        print('觸發了__getattr__(),要訪問物件的{}成員'.format(attr))
        return '訪問成員不存在'
        pass
    # 訪問成員的時候觸發
    def __getattribute__(self,attr):
        print('觸發了__getattribute__(),要訪問物件的{}成員'.format(attr))
        # 一定不能使用self.__getattribute__(self,attr),否則會導致遞迴死迴圈,使用object的方法訪問
        if attr in ('name','sex','age','height','test'):
            return object.__getattribute__(self,attr)
        else :
            return '返回預設值'
    # 測試方法
    def test(self):
        print('呼叫測試方法test')
複製程式碼
# 例項化Test類,分別訪問物件的name(存在的成員屬性)、test(存在的成員方法)、wight(不存在的成員屬性),驗證結果
xm = Human('小明','男',18)
複製程式碼
# name(存在的成員屬性),觸發__getattribute__()方法正常返回,就不會再觸發__getattr__()方法了
print(xm.name)
複製程式碼
觸發了__getattribute__(),要訪問物件的name成員
小明
複製程式碼
# test(存在的成員方法),呼叫和訪問成員方法都會觸發__getattribute__()方法
print(xm.test)
print()
xm.test()
複製程式碼
觸發了__getattribute__(),要訪問物件的test成員
<bound method Human.test of <__main__.Human object at 0x0000018D59C5B080>>

觸發了__getattribute__(),要訪問物件的test成員
呼叫測試方法test
複製程式碼
# wight(不存在的成員屬性)
# 雖然wight不存在,但是在__getattribute__(self,attr)方法中對於訪問xm.wight時設定返回‘返回預設值’
# __getattribute__(self,attr)正常返回時並沒有觸發__getattr__(self,attr)方法
print(xm.wight)


print('\n####################################################################\n')


# 但是當訪問height成員屬性時,__getattribute__(self,attr)方法並沒有直接返回,
# 而是使用object.__getattribute__(self, attr)訪問物件對的成員,從而觸發了__getattr__()
print(xm.height)
複製程式碼
觸發了__getattribute__(),要訪問物件的wight成員
返回預設值

####################################################################

觸發了__getattribute__(),要訪問物件的height成員
觸發了__getattr__(),要訪問物件的height成員
訪問成員不存在
複製程式碼

相關文章