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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542089.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542089.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542089.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ad18原理圖器件批量修改_Altium Designer 15原理圖設計基礎

Altium Designer 15成為越來越多電子設計開發工程師EDA電路設計軟件的首選&#xff0c;在學校學習Altium Designer的也越來較多&#xff0c;像單片機開發學習一樣&#xff0c;EDA設計只要學會了&#xff0c;再學其他的設計軟件就容易多了。上一節分享了《Altium Designer 15集成…

c++freopen函數_使用示例的C語言中的freopen()函數

cfreopen函數C語言中的freopen()函數 (freopen() function in C) Prototype: 原型&#xff1a; FILE* freopen(const char *str, const char *mode, FILE *stream);Parameters: 參數&#xff1a; const char *str, const char *mode, FILE *streamReturn type: FILE* 返回類型…

python—文件

1 . 文件的基本操作&#xff1a; 文件讀取三部曲&#xff1a; 打開操作關閉&#xff08;如果不關閉會占用文件描述符&#xff09; 打開文件&#xff1a; f open(/tmp/passwdd,w)操作文件&#xff1a; 1 . 讀操作&#xff1a; f.read()content f.read()print(content) 2 …

基本概念學習(7000)--P2P對等網絡

對等網絡&#xff0c;即對等計算機網絡&#xff0c;是一種在對等者&#xff08;Peer&#xff09;之間分配任務和工作負載的分布式應用架構[1] &#xff0c;是對等計算模型在應用層形成的一種組網或網絡形式。“Peer”在英語里有“對等者、伙伴、對端”的意義。因此&#xff0c;…

c語言for循環++_C ++程序使用循環查找數字的冪

c語言for循環Here, we are going to calculate the value of Nth power of a number without using pow function. 在這里&#xff0c;我們將不使用pow函數來計算數字的N 次冪的值 。 The idea is using loop. We will be multiplying a number (initially with value 1) by t…

廈門one_理想ONE真是“500萬內最好的車”?

提起羅永浩&#xff0c;不少人還停留在“砸冰箱、造手機”等早期事件。隨著網絡直播的興起&#xff0c;羅永浩轉戰直播帶貨行業&#xff0c;但老羅畢竟是老羅&#xff0c;雷人語錄一點沒比以前少。前一段時間&#xff0c;羅永浩在微博中稱&#xff1a;“理想ONE是你能在這個價位…

Data Collection

眾所周知&#xff0c;計算機領域論文是要以實驗為基礎的&#xff0c;而實驗的原料就是數據。不管是在圖像&#xff0c;文字或者語音領域&#xff0c;開源的數據都十分寶貴和重要。這里主要收集各領域的一些常用的公開數據集。 計算機視覺&#xff1a; 【ImageNet】 【Caltech P…

python—os模塊、時間模塊

os模塊 作用&#xff1a;os模塊是python標準庫中的一個用于訪問操作系統功能的模塊&#xff0c; os模塊提供了其他操作系統接口&#xff0c;可以實現跨平臺訪問。 使用&#xff1a; 1 . 返回操作系統類型 &#xff1a;os.name 值為&#xff1a;posix 是linux操作系統 值為&…

kotlin鍵值對數組_Kotlin程序檢查數組是否包含給定值

kotlin鍵值對數組Given an array and an element, we have to check whether array contains the given element or not. 給定一個數組和一個元素&#xff0c;我們必須檢查數組是否包含給定的元素。 Example: 例&#xff1a; Input:arr [34, 56, 7, 8, 21, 0, -6]element to…

enter sleep mode黑屏怎么解決_【linux】 不要再暴力關機了,講講我最近遇到的問題和完美解決方案...

歡迎關注我的個人公眾號&#xff1a;AI蝸牛車前言結束了每天的緊張的工作&#xff0c;這兩天真的有些肝。這兩天打打字&#xff0c;突然感覺手指頭疼起來了&#xff0c;想意識到成天打了十多個小時的鍵盤&#xff0c; 手指頭都疲勞了 之后這兩天基本上除了基本的吃睡&#xff…

重復T次的LIS的dp Codeforces Round #323 (Div. 2) D

http://codeforces.com/contest/583/problem/D 原題&#xff1a;You are given an array of positive integers a1,?a2,?...,?an??T of length n??T. We know that for any i?>?n it is true that ai??ai?-?n. Find the length of the longest non-decreasing …

微擎pc 導入前綴_段覆蓋前綴| 8086微處理器

微擎pc 導入前綴As we already know that the effective address is calculated by appending the segment registers value and adding up the value of the respective offset. But what if we want to choose some other offset than the assigned one. 眾所周知&#xff0…

python—面向對象

面向過程 面向對象&#xff1a; 面向過程&#xff1a;—側重于怎么做&#xff1f; 1.把完成某一個需求的 所有步驟 從頭到尾 逐步實現 2.根據開發要求&#xff0c;將某些功能獨立的代碼封裝成一個又一個函數 3.最后完成的代碼&#xff0c;就是順序的調用不同的函數 特點&#…

5中bug vue_蘋果官網出BUG!這些都只要一兩百元

近日&#xff0c;有網友在網上反饋稱&#xff0c;他發現蘋果官網商城出現了BUG&#xff01;眾多上千元的產品&#xff0c;BUG價只需一兩百元。比如Shure MOTIV MV88 Digital立體聲電容式麥克風配件。正常售價1288元&#xff0c;而BUG后的價格是235元。UBTECH Jimu Astrobot Cos…

常用壓縮,解壓與打包

常用壓縮格式&#xff1a; .zip .zg .bz2 .tar.gz .tar.bz2.zip格式壓縮zip 壓縮文件名 源文件#壓縮文件注&#xff1a;壓縮文件名寫.zip后綴是為了標記該文件的壓縮類型&#xff0c;方便管理。注&#xff1a;在壓縮時有壓縮格式轉換&#xff0c;所以當源文件很小時&#xff0c…

css禁用選中文本_使用CSS禁用文本選擇突出顯示

css禁用選中文本Introduction: 介紹&#xff1a; Texts are the most fundamental elements of any websites or web pages, they form the basis of the web pages or websites because if you don’t write something that you will not be able to present anything. There…

CDN加速實現—varnish

CDN介紹&#xff1a; 1 . 對cdn的理解&#xff1a; CDN的全稱是&#xff08;Content Delivery Network&#xff09;&#xff0c;即內容分發網絡&#xff1b;加速器&#xff0c;反向代理緩存。CDN系統能夠實時的根據網絡流量和各節點的連接&#xff0c;負載狀況以及到用戶的舉例…

3dmax如何拆分模型_3dmax制作裝飾柜1

大家好&#xff0c;今天我來為大家講解一下如何利用3dmax制作裝飾柜。我們需要制作裝飾柜模型&#xff0c;當我們為它添加一個材質后&#xff0c;它就是這樣的效果。單擊創建&#xff0c;選擇圖形&#xff0c;對象為樣條線&#xff0c;選擇矩形在場景中進行創建。單擊修改&…

TODO:macOS上ThinkPHP5和Semantic-UI集成

TODO&#xff1a;macOS上ThinkPHP5和Semantic-UI集成1. 全局安裝 (on OSX via homebrew)Composer 是 homebrew-php 項目的一部分2. 把Xcode升級到8.1后繼續安裝Composer3. 使用composer創建TP5項目MWL-Dispatchcomposer create-project topthink/think MWL-Dispatch4. 配置apac…

np.expm1_JavaScript中帶有示例的Math.expm1()方法

np.expm1JavaScript | Math.expm1()方法 (JavaScript | Math.expm1() Method) Math operations in JavaScript are handled using functions of math library in JavaScript. In this tutorial on Math.expm1() method, we will learn about the expm1() method and its workin…