日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python—装饰器

發布時間:2025/3/11 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python—装饰器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

裝飾器概念:
把一個函數當作參數傳遞給一個函數,返回一個替代版的函數
本質上就是一個返回函數的函數
在不改變原函數的基礎上,給函數增加功能
python 中裝飾器做的事情!它們封裝一個函數,并且用這樣或者那樣的方式來修改它的行為
@ 符號,那只是一個簡短的方式來生成一個被裝飾的函數

def outer(func):def inner():print('*****')func()return inner@outer def func():print('have a nice day!') @outer def func2():print('hello world') func() func2()運行結果: ***** have a nice day! ***** hello world

裝飾器示例:

import time# 裝飾器 def decorator(func):def wrapper():print(time.time())func()return wrapper@decorator # 調用裝飾器 def f1():print('This is a function...')def f2(): # 沒有裝飾器print('This is a function...')f1() f2()運行結果: 1560391414.8582878 f1 This is a function... This is a function... f2

裝飾器實現一個函數計時器

import time import string import random import functoolsli = [random.choice(string.ascii_letters)for i in range(1000)]def timeit(fun):# 問題1:被裝飾的函數有返回值的時候怎么辦?# 問題2:被裝飾的函數如何保留自己的函數名和幫助信息文檔?@functools.wraps(fun)def wapper(*args, **kwargs):"""這是一個wapper函數"""# 在函數的執行之前start_time = time.time()# 執行函數res = fun(*args, **kwargs)# 在函數執行之后end_time = time.time()print('運行的時間為:%.6f' % (end_time - start_time))return resreturn wapper@timeit def con_add():s = ''for i in li:s += (i + '+')print(s)@timeit def join_add():print('+'.join(li))con_add() join_add()@timeit def fun_list(n):"""這是fun_list函數,被timeit裝飾"""return [2 * i for i in range(n)] @timeit def fun_map(n):"""這是fun_map函數,被timeit裝飾"""return list(map(lambda x:x*2,range(n)))# fun_list(5000) # fun_map(5000) print(fun_list.__doc__) print(fun_map.__doc__) print(fun_list.__name__) print(fun_map.__name__)

創建裝飾器, 要求如下:
1 . 創建add_log裝飾器, 被裝飾的函數打印日志信息;
2 . 日志格式為: [字符串時間] 函數名: xxx,
運行時間:xxx, 運行返回值結果:xxx

import time import functools print(time.ctime())def add_log(func):@functools.wraps(func)def wrapper(*args,**kwargs):start_time = time.time()res = func(*args,**kwargs)end_time = time.time()print('[%s] 函數名:%s,運行時間:%.6f,運行返回值的''結果:%d' %(time.ctime(),func.__name__,end_time-start_time,res))return resreturn wrapper @add_log def add(x,y):time.sleep(1)return x+y add(1,10)

多個裝飾器裝飾函數,從上到下執行

def decorator_a(fun):def inner_a(*args,**kwargs):print('Get in inner_a')return fun(*args,**kwargs)return inner_adef decorator_b(fun):def inner_b(*args,**kwargs):print('Get in inner_b')return fun(*args,**kwargs)return inner_b@decorator_b @decorator_a def f(x):print('Gat in f')return x*2f(1)

多個裝飾器的應用場景:
會采用多個裝飾器先驗證是否登陸成功,再驗證登陸權限是否足夠
inspect.getcallargs會返回一個字典,

import inspect import functools def is_admin(fun):@functools.wraps(fun)def wrapper(*args,**kwargs):# inspect.getcallargs 會返回一個字典,# key值:形參 value:對應的實參數inspect_res = inspect.getcallargs(fun,*args,**kwargs)print('inspect的返回值是:%s' %(inspect_res))if inspect_res.get('name') == 'root':temp = fun(*args,**kwargs)return tempelse:print('not root user,no permisson add user')return wrapper login_session = ['root','admin','redhat']def is_login(fun):@functools.wraps(fun)def wrapper(*args,**kwargs):if args[0] in login_session:temp = fun(*args,**kwargs)return tempelse:print('Error:%s 沒有登陸成功' %(args[0]))return wrapper @is_login @is_admin def add_user(name):print('add user~') add_user('root')

代參數的裝飾器

import functools import timedef log(kind):def add_log(func):@functools.wraps(func)def wrapper(*args,**kwargs):start_time = time.time()res = func(*args,**kwargs)end_time = time.time()print('<%s>[%s] 函數名:%s,運行時間:%.6f,運行返回值的''結果:%d' %(kind,time.ctime(),func.__name__,end_time-start_time,res))return resreturn wrapperreturn add_log @log('debug') def add(x,y):time.sleep(1)return x+y print(add(1,2))

練習題:
編寫裝飾器required_types, 條件如下:
1). 當裝飾器為@required_types(int,float)確保函數接收到的每一個參數都是int或者float類型;
2). 當裝飾器為@required_types(list)確保函數接收到的每一個參數都是list類型;
3). 當裝飾器為@required_types(str,int)確保函數接收到的每一個參數都是str或者int類型;
4). 如果參數不滿足條件, 打印 TypeError:參數必須為xxxx類型

import functools def required_types(*kinds):def required_int(fun):@functools.wraps(fun)def wrapper(*args, **kwargs):for i in args:if not isinstance(i, kinds):# print('TypeError:參數必須為',kinds)# breakraise TypeError('參數必須為%s,%s' % kinds)else:res = fun(*args, **kwargs)return resreturn wrapperreturn required_int# @required_types(float, float) # def add(a, b): # return a + b # # print(add(1.1, 2.0)) 運行結果為:3.1# @required_types(list) # def add(a, b): # return a + b # # print(add(1.1, 2.0)) 運行結果為: Traceback (most recent call last):File "/home/kiosk/PycharmProjects/20190523/練習.py", line 65, in <module>print(add(1.1, 2.0))File "/home/kiosk/PycharmProjects/20190523/練習.py", line 42, in wrapperraise TypeError('參數必須為%s,%s' % kinds) TypeError: not enough arguments for format string

總結

以上是生活随笔為你收集整理的python—装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。