python定製訂單 python 訂製類

2021-10-12 15:57:45 字數 2885 閱讀 1796

__str__

__repr__

__iter__

__next__

__getitem__

__getattr__

正常情況下,當我們呼叫類的方法或屬性時,如果不存在,就會報錯。比如定義student類:

classstudent(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。

classstudent(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.score99

返回函式也是完全可以的:

classstudent(object):def __getattr__(self, attr):if attr=='age':return lambda: 25

只是呼叫方式要變為:

>>>s.age()25

注意,只有在沒有找到屬性的情況下,才呼叫__getattr__,已有的屬性,比如name,不會在__getattr__中查詢。

此外,注意到任意呼叫如s.abc都會返回none,這是因為我們定義的__getattr__預設返回就是none。要讓class只響應特定的幾個屬性,我們就要按照約定,丟擲attributeerror的錯誤:

classstudent(object):def __getattr__(self, attr):if attr=='age':return lambda: 25

raise attributeerror('\'student\' object has no attribute \'%s\'' % attr)

這實際上可以把乙個類的所有屬性和方法呼叫全部動態化處理了,不需要任何特殊手段。

這種完全動態呼叫的特性有什麼實際作用呢?作用就是,可以針對完全動態的情況作呼叫。

舉個例子:

如果要寫sdk,給每個url對應的api都寫乙個方法,那得累死,而且,api一旦改動,sdk也要改。

利用完全動態的__getattr__,我們可以寫出乙個鏈式呼叫:

lass chain(object):def __init__(self, path=''):

self._path=pathdef __getattr__(self, path):return chain('%s/%s' %(self._path, path))def __str__(self):returnself._path__repr__ = __str__

試試:>>>chain().status.user.timeline.list'/status/user/timeline/list'

這樣,無論api怎麼變,sdk都可以根據url實現完全動態的呼叫,而且,不隨api的增加而改變!

還有些rest api會把引數放到url中,比如github的api:

get /users/:user/repos

呼叫時,需要把:user替換為實際使用者名稱。如果我們能寫出這樣的鏈式呼叫:

chain().users('michael').repos

就可以非常方便地呼叫api了。有興趣的童鞋可以試試寫出來。

__call__

乙個物件例項可以有自己的屬性和方法,當我們呼叫例項方法時,我們用instance.method()來呼叫。能不能直接在例項本身上呼叫呢?在python中,答案是肯定的。

任何類,只需要定義乙個__call__()方法,就可以直接對例項進行呼叫。請看示例:

classstudent(object):def __init__(self, name):

self.name=namedef __call__(self):print('my name is %s.' % self.name)

呼叫方式如下:

>>> s = student('michael')>>> s() #self引數不要傳入

my name is michael.

__call__()還可以定義引數。對例項進行直接呼叫就好比對乙個函式進行呼叫一樣,所以你完全可以把物件看成函式,把函式看成物件,因為這兩者之間本來就沒啥根本的區別。

如果你把物件看成函式,那麼函式本身其實也可以在執行期動態建立出來,因為類的例項都是執行期建立出來的,這麼一來,我們就模糊了物件和函式的界限。

那麼,怎麼判斷乙個變數是物件還是函式呢?其實,更多的時候,我們需要判斷乙個物件是否能被呼叫,能被呼叫的物件就是乙個callable物件,比如函式和我們上面定義的帶有__call__()的類例項:

>>>callable(student())

true>>>callable(max)

true>>> callable([1, 2, 3])

false>>>callable(none)

false>>> callable('str')

false

通過callable()函式,我們就可以判斷乙個物件是否是「可呼叫」物件。

python定製訂單 觸發定製的Python業務

您可能知道,我們可以採用python指令碼語言來提供業務。這種方式可以非常靈活地滿足許多客戶各種各樣的需求。但是某些東西就不那麼靈活,例如業務的觸發方式。以前的mss版本在卡號業務中,固定了業務觸發方式。也就是說,只有被叫號碼是 300 的呼叫才會觸發卡號業務。有些客戶就是不喜歡這個號碼,還有些客戶...

python定製 python中定製類

1 python中 str 和repr 如果要把乙個類的例項變成 str,就需要實現特殊方法 str classperson object def init self,name,gender self.name name self.gender genderdef str self return p...

Python 定製序列

1 python中的三大容器 列表list,元組tuple,字串string 2 python允許我們定製乙個不可變的容器,如string,中就不能有修改容器的資料方法,如 setitem delitem 3 如果希望定製的容器支援reversed 內建函式,則容器中需定義 reversed 方法,...