大家好,我是金魚座,一個走在測試領域這片藍海中, 蹉跎前行的技術渣渣,唯有一直走下去,也許能改變點什么,加油!
今天看到一個有趣關于裝飾器活用的一種表達,之前在使用裝飾器的時候,我們很多時候都是有參數,無參數等進行區分,比如一個典型的裝飾器函數有參數的情況
def log2(param):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not param:
print('%s no param' % (param))
else:
print('%s in %s()' % (param, func.__name__))
return func(*args, **kwargs)
return wrapper
return decorator
@log2("")
def now3():
print("now3")
@log2("test")
def now4():
print("now4")
如上代碼可以看出就是一個普通裝飾器方法帶參數的例子,通過參數的判斷來調整輸出,結果如下:
image.png
那么如果我想實現一種如下圖的裝飾器顯示方式,那個該怎么處理呢??
image.png
如圖片所示,我想用一個裝飾器方法名既能充當有參數的情況,也能充當無參數的情況
這是一個很好的方式, 廢話就不說了,上代碼
import functools
def log(param):
# 不存在可調用對象的情況下
if callable(param):
def wrapper(*args, **kwargs):
print('%s function()' % (param.__name__,))
param(*args, **kwargs)
return wrapper
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (param, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
如代碼所示,通過callable來判斷當前是否是可調用對象,如果是可調用對象則作為無參數來進行使用,如果不是一個可調用對象,則作為一個普通參數來處理
image.png
至于為什么是這個情況呢?
下面簡單說一下自己的理解
我們應該知道作為一個裝飾器他們再執行的時候,是具有一下特點的,為了方便找了一個截圖
image.png
如圖所示 一個 @log 等于 如下表達:
t = log(f1) 通過return wrapper返回執行對象
t()
通過這表達式來解讀上面的實現原來就可以明白
image.png
通過判斷當前的這個param是否是f1這個方法的對象,如果是方法的對象則理解為普通的@log裝飾器,如果是這個param不是一個f1這個對象而是一個普通的“測試‘這個參數,那么就當作一個@log(”測試')來進行處理
這就是上面之所以可以實現合并表達的主要原因
當然這些都是自己的一種理解認知,如果有不合適的地方,也歡迎朋友指正,謝謝