測試平臺系列(65) 非同步方法裝飾器
大家好~我是
米洛
!
我在從0到1打造一個開源平臺, 也在編寫一套完整的介面測試平臺系列教程
,希望大家能夠多多支援。
歡迎關注我的公眾號測試開發坑貨
,獲取最新文章教程!
回顧
上一節我們完善
了一整套測試用例執行的流程
,這一節我們來講講async方法的裝飾器
。
在此之前,我們先來看下用於非同步方法
的裝飾器。
日誌裝飾器
還記得我們之前編寫過的日誌裝飾器
嗎?不記得的話也沒關係,咱們現滷
一個。
import functools def log(func): @functools.wraps(func) def wrapper(*args, **kwargs): print("正在執行方法: ", func.__name__) print("引數: ", *args, *[f"{k}={v} " for k, v in kwargs.items()]) result = func(*args, **kwargs) print("執行結果: ", result) return result return wrapper @log def print_user(name, age, height=180): return f"hello, {name}. Age: {age}, Height: {height}" if __name__ == "__main__": print_user("klose", 43, height=182)
我們編寫了一個print_user
(列印使用者資訊)的方法,並給他加上了log裝飾器,這樣一旦這個方法執行
了,我們就會輸出這些資料到日誌裡面。
因為這裡我沒有現成的日誌包,所以我用了print代替。輸入到日誌需要記錄什麼內容呢?
-
呼叫了什麼方法
-
方法的引數是什麼
-
方法的返回值是什麼
我們來看看輸出:
就是這麼個場景,普通的裝飾器
實現如上。接著我們來思考一個問題,如果我們的方法是非同步
的,在裝飾器不變的情況下,會是什麼輸出呢?
求豆麻袋。
我們來進行下簡單的改造。
async方法的裝飾器
@log async def print_user(name, age, height=180): return f"hello, {name}. Age: {age}, Height: {height}"
只需要把print_user方法改為async
,然後用asyncio.run執行print_user
方法即可。來看下輸出:
@log
async def print_user(name, age, height=180):
return f"hello, {name}. Age: {age}, Height: {height}"
if __name__ == "__main__":
asyncio.run(print_user("klose", 43, height=182))
可以看到,執行結果
變成了coroutine
了,也就是說拿不到返回值
了。
那麼接下來就進入我們的改造階段
裝飾器
也支援非同步方法。
查詢資料
通過google,我們發現asyncio有這樣一個方法: iscoroutinefunction
看名字就知道,是判斷一個function
是不是coroutine,如果這招有用的話,那說明我們的問題能夠解決了。
def log(func):
if asyncio.iscoroutinefunction(func):
@functools.wraps(func)
async def wrapper(*args, **kwargs):
print("正在執行方法: ", func.__name__)
print("引數: ", *args, *[f"{k}={v} " for k, v in kwargs.items()])
result = await func(*args, **kwargs)
print("執行結果: ", result)
return result
else:
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("正在執行方法: ", func.__name__)
print("引數: ", *args, *[f"{k}={v} " for k, v in kwargs.items()])
result = func(*args, **kwargs)
print("執行結果: ", result)
return result
return wrapper
我們把程式碼改成這個樣子: 可以看到,裝飾器又和上一次講的一樣,進入了一個分水嶺,當iscoroutine成立的時候,形成了一個async
的裝飾器,反之則是普通的裝飾器。
試試效果先
再試試把log放到普通方法上面:
程式碼冗餘
細心的朋友可能發現了,3個print的內容都是很重複
的,但是ide並沒有提示你,但其實這幾塊內容是完全可以封裝起來的。
這大概就是順手為之,慢慢就形成了屎山程式碼
吧~
所以核心方法是asyncio.iscoroutinefunction
, 你學會了嗎?
今天的內容就介紹到這裡了,大家沒點關注的點個關注
,點了關注的點個贊
,點了讚的點個在看
,點了在看的點個讚賞
,點了讚賞的點個退出
。