__getattr__动态获取接口
生活随笔
收集整理的這篇文章主要介紹了
__getattr__动态获取接口
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
# -*- coding:utf-8 -*-
#在看廖雪峰的python3.5教學時,看到面向對象高級編程_定義類
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319098638265527beb24f7840aa97de564ccc7f20f6000
百度了很久沒有找到想要的答案,想了很久,總結了一點點心得,寫的不好,希望大家指正
途中發現好多問題,包括前面沒有理解的,停留了好久
##################################
#正常情況下,當我們調用類的方法或屬性時,如果不存在,就會報錯。比如定義Student類:class Student(object):def __init__(self):self.name = 'Michael'#調用name屬性,沒問題,但是,調用不存在的score屬性,就有問題了:
#>>> s = Student()
#>>> print(s.name)
#Michael
#>>> print(s.score)
#Traceback (most recent call last):
# ...
#AttributeError: 'Student' object has no attribute 'score'#錯誤信息很清楚地告訴我們,沒有找到score這個attribute。
#要避免這個錯誤,除了可以加上一個score屬性外,Python還有另一個機制,那就是寫一個__getattr__()方法,動態返回一個屬性。修改如下:class Student(object):def __init__(self):self.name = 'Michael'def __getattr__(self, attr):if attr=='score':return 99#當調用不存在的屬性時,比如score,Python解釋器會試圖調用__getattr__(self, 'score')來嘗試獲得屬性,這樣,我們就有機會返回score的值:#>>> s = Student()
#>>> s.name
#'Michael'
#>>> s.score
#99#返回函數也是完全可以的:class Student(object):def __getattr__(self, attr):if attr=='age':return lambda: 25#只是調用方式要變為:
#>>> s.age()
#25#注意,只有在沒有找到屬性的情況下,才調用__getattr__,已有的屬性,比如name,不會在__getattr__中查找。#此外,注意到任意調用如s.abc都會返回None,這是因為我們定義的__getattr__默認返回就是None。要讓class只響應特定的幾個屬性,我們就要按照約定,拋出AttributeError的錯誤:class Student(object):def __getattr__(self, attr):if attr=='age':return lambda: 25raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)#這實際上可以把一個類的所有屬性和方法調用全部動態化處理了,不需要任何特殊手段。#這種完全動態調用的特性有什么實際作用呢?作用就是,可以針對完全動態的情況作調用。#舉個例子:#現在很多網站都搞REST API,比如新浪微博、豆瓣啥的,調用API的URL類似:#http://api.server/user/friends
#http://api.server/user/timeline/list
#如果要寫SDK,給每個URL對應的API都寫一個方法,那得累死,而且,API一旦改動,SDK也要改。#利用完全動態的__getattr__,我們可以寫出一個鏈式調用:class Chain(object):def __init__(self, path=''):self._path = pathdef __getattr__(self, path):return Chain('%s/%s' % (self._path, path))def __str__(self):return self._path__repr__ = __str__#測試結果
#>>> Chain().status.user.timeline.list
#'/status/user/timeline/list'#==========================================
#這里想了很久;查看一個類
#創建了一個空的類,再創建一個實例實例class Student(object):pass#bart = Student()
#變量bart指向的就是一個Student的實例#再看剛剛那個例子,Chain()表示類自己(本身);
#Chain().status表示的類Chain()的status屬性,此時函數就去尋找Chain的status屬性
#但發現沒有此屬性,這時特殊函數__getattr__起作用了,它幫我們創建屬性status屬性
#根據定義的方法將新的屬性前加一個'/'#初始化使用了默認參數path為空
#def __init__(self, path=''):#連貫起來就是
#1.先定義類Chain()的一個屬性path,切默認值為'',為空
#2.定義方法,特殊函數__getattr__遇到未定義的屬性默認返回空,不報錯
#由于定義了方法,所以返回return Chain('%s/%s' % (self._path, path))
#即將未定義的額屬性以'/'為分隔符輸出
#3.方法def __str__(self):的作用是打印字符串#當然還有細節沒有搞清楚
#1.class中的各方法參數是表示同一個值嗎?
#即三個方法中的self._path相關么?
轉載于:https://www.cnblogs.com/irockcode/p/7828737.html
總結
以上是生活随笔為你收集整理的__getattr__动态获取接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lab 2 EIGRP Default
- 下一篇: windows系统OLLVM + NDK