影片連結https://zhuanlan。zhihu。com/p/562586782
什麼是魔法函式?
是以雙下劃線開頭和雙下劃線結尾命名的特殊函式,不需要開發者呼叫,由Python直譯器呼叫。
可呼叫物件的概念:在python中,能夠使用名稱加()執行的物件都是可呼叫物件。
很顯然所有的函式都是可呼叫物件,那麼類例項物件是呼叫物件嗎?
實驗下:
報錯了,錯誤資訊提示Student物件不是一個可呼叫物件。
檢測一個物件是否可呼叫還可以使用callable函式。
返回False,也說明了Student物件不是一個可呼叫物件。
那麼這麼才能拿讓類例項物件變成可呼叫物件呢?
只要類實現了魔法函式__call__即可,我們試下。
很明顯實現了__call__之後,Student物件變成了可呼叫物件;
其中__call__不需要要開發者來呼叫,它屬於特殊函式,直譯器會去呼叫的。
為什麼要將了轉化成可呼叫物件呢?哪些場景使用?
可呼叫物件,讓類例項物件能夠像函式一樣接收引數,好處是更加簡潔,不需要使用 物件。方法()。
使用場景:
1。在一些驗證器中使用,舉個例子:
import re
class PhoneValidator():
‘’‘DEC:手機號格式合法驗證器’‘’
def __call__(self, *args, **kwargs):
reg = ‘^1(3[0-9]|4[5,7]|5[0,1,2,3,5,6,7,8,9]|6[2,5,6,7]|7[0,1,7,8]|8[0-9]|9[1,8,9])\d{8}$’
phone = args[0]
if not re。match(reg, phone):
print(“phone is validate。”)
else:
print(“phone is invalidate。”)
phone_validator = PhoneValidator()
phone_validator(“13735468254”)
phone_validator(“10735468254”)
結果:
phone is invalidate。
phone is validate。
你可能會為那為什麼不使用函式呢?類有更好的擴充套件性,你可能還需要做其他的事情呢?
所以我們需要的是函式但是又不僅僅只是函式。
2。在類裝飾器中使用,在裝飾器章節詳細看下類裝飾器。
‘’‘
描述:雖然裝飾器是用類實現的,但是最終用來替換原函式的物件,仍然是一個處在__call__方法裡的閉包函式
’‘’
import time
import random
from functools import wraps
class Timer:
“”“裝飾器:列印函式的耗時
:param print_args:是否打印發發那個發名和引數,預設為False
”“”
def __init__(self,print_args):
self。print_args = print_args
def __call__(self, func):
@wraps(func)
def decorated(*args, **kwargs):
‘’‘
desc:jdhfksjdf
@param:args,
’‘’
st = time。perf_counter()
ret = func(*args, **kwargs)
if self。print_args:
print(f‘“{func。__name__}”,args:{args},kwargs:{kwargs}’)
print(“time cost:{} seconds”。format(time。perf_counter()-st))
return ret
return decorated
@Timer(print_args=True)
def random_sleep():
print(“random”)
if __name__ == ‘__main__’:
random_sleep()