Python之路【第十七篇】:裝飾器

寫代碼的時候有一個原則,開放封閉原則(面向對象):對某些東西開放,對某些封閉,在裝飾器這里,函數內部是封閉的,不允許改變函數的內部。

裝飾器用來裝飾函數,可以讓函數在執行之前或者執行之后,做一些操作,讓函數調用者的操作不變,就能在執行前后做一些操作。簡單來說,裝飾器感覺就類似于裝修,提供一些額外的功能。

裝飾器的本質就是將原函數封裝到另一個函數里面。

裝飾器原理剖析

關鍵點1

def f1():print('1')
def f1():print('2')
f1()

上面這段函數執行后,輸出的結果為2,因為python解釋器從上往下執行,先把第一個f1放進內存,碰到第二個f1函數后又把它放進內存,所以f1指的是第二個函數的內容。

關鍵點2

@符號:

    @符號具有特殊性,@函數名,碰到后,先執行函數,并且將其下面的函數名當作參數,如:

def outer(func):pass
@outer
def f1():pass
def f2():pass

碰到@outer之后,先執行outer函數,然后將f1作為參數,此時func=f1(原來的f1函數)

outer的返回值賦值給f1,此時f1=outer返回值,所以以后再執行f1,就執行新的f1函數

?關鍵點3

只要函數用了裝飾器,函數就會重新定義為裝飾器的內層函數,所以如果函數有參數的話,裝飾器的內層函數也要有相應的參數來接收,即inner函數要有相應的參數,同時,func函數等于原來的函數,所以func函數也要有相應的參數

inner(*args,**kwargs)

ret? = func(*args,**kwargs)

以后寫裝飾器就按照上面的寫法來,這樣就不用擔心參數的問題了,碉堡了。

裝飾器例子:

#!/usr/bin/env python
# -*- coding:utf-8 -*-def outer(func):def inner(*args,**kwargs):print('')ret = func(*args,**kwargs)print('')return retreturn inner@outer
def f1(a1):print('aa')return a1@outer
def f2(s1,s2):print('bb')return s1,s2ret1 = f1(1)ret2 = f2(2,3)print(ret1,ret2)

上面的程序輸出結果為:


aa


bb

1 (2, 3)

可以看到,在不改變函數的基礎上,函數執行了一些別的操作。上面這是一個裝飾器裝飾一個或多個函數的場景

多個裝飾器裝飾一個函數

#!/usr/bin/env python
# -*- coding:utf-8 -*-def outer0(func):def inner(*args,**kwargs):print('before')ret = func(*args,**kwargs)print('after')return retreturn inner
def outer(func):def inner(*args,**kwargs):print('')ret = func(*args,**kwargs)print('')return retreturn inner
@outer0
@outer
def f1():print('self')return None
f1()

輸出結果為:

before

self

after

可以這樣理解:

#part1
#一個新的函數,不妨叫這個函數為index
@outer
def f1():print('self')return None

然后代碼就變成了下面這樣:

#part2
@outer0 def index():pass

最后函數的執行順序是這樣的:先執行最外層的part2,即先輸出before,在執行index函數,最后輸出after,執行index函數的時候,就是執行part1,先輸出'你',在輸出'self',再輸出'好'。

轉載于:https://www.cnblogs.com/ronghe/p/8681358.html

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

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

相關文章

HALCON示例程序measure_chip.hdev芯片封裝檢測

HALCON示例程序measure_chip.hdev芯片封裝檢測 示例程序源碼(加注釋) 關于顯示類函數解釋 dev_update_off () read_image (Image, ‘die_on_chip’) get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width * 2, He…

工業機器人智能發展:視覺和觸覺感應簡化

機器人工業協會(Robotic Industries Association)指出,從2003到2005年間,北美機器人工業以20%的平均年增長率發展。在汽車市場需求疲軟以及外國廠商的壓力不斷增加的背景下,這一成就是如何取得的?成本的普遍…

ASP站點無法訪問怎么辦

確保啟用了目錄瀏覽功能 轉載于:https://www.cnblogs.com/acetaohai123/p/6571257.html

五、案例-指令參考-freemarker指令、表達式

案例-指令參考描述&#xff1a;本人自己測試寫了一遍&#xff0c;如有錯的地方&#xff0c;懂freemarker的朋友望指點指點&#xff01; 案例-指令參考 表達式 一、 Assign 1、<#assign name1"北京" name2"上海" name3"廣東"> 調用&#xf…

PartitionMotionSearch()函數

encode_one_macroblock()函數中的運動估計分為兩大塊&#xff0c;對于宏塊級的三種模式&#xff0c;分塊后直接對patition依次調用PartitionMotionSearch()函數&#xff1b;而對于亞宏塊級的&#xff08;含8x8, 8x4,4x8,4x4&#xff09;模式&#xff0c;首先將宏塊拆分為4個88子…

201521123017 《Java程序設計》第4周學習總結

1. 本周學習總結 2. 書面作業 Q1.注釋的應用 使用類的注釋與方法的注釋為前面編寫的類與方法進行注釋&#xff0c;并在Eclipse中查看。(截圖) Q2.面向對象設計(大作業1&#xff0c;非常重要) 2.1 將在網上商城購物或者在班級博客進行學習這一過程&#xff0c;描述成一個故事。…

完整的VAL3程序

start() begin//延時10秒 delay(5)//初始化變量call init()//清空原有運動堆棧resetMotion()//建立上電任務taskCreate "robotpower",100,robotpower()wait(isPowered())//建立生產任務taskCreate "ProductionCycle",10,ProductionCycle()//建立安全區域…

iOS WebView 加載本地資源(圖片,文件等)

NSString *path [[NSBundle mainBundle] pathForResource:"關于.docx" ofType:nil]; NSURL *url [NSURL fileURLWithPath:path]; NSLog("%", [self mimeType:url]); //webview加載本地文件&#xff0c;可以使用加載數據的方式 //第一個誒參數是一個N…

本文以H264視頻流為例,講解解碼流數據的步驟。

本文以H264視頻流為例&#xff0c;講解解碼流數據的步驟。 為突出重點&#xff0c;本文只專注于討論解碼視頻流數據&#xff0c;不涉及其它&#xff08;如開發環境的配置等&#xff09;。如果您需要這方面的信息&#xff0c;請和我聯系。 準備變量 定義AVCodecContext。如…

2008-2021年商業銀行數據(農商行、城商行、國有行、股份制銀行)

2008-2021年商業銀行數據&#xff08;農商行、城商行、國有行、股份制銀行&#xff09; 1、時間&#xff1a;2008-2021年 2、范圍&#xff1a;1700銀行 3 、指標&#xff1a;證券簡稱、year、證券代碼、資產總計、負債合計、所有者權益合計、利潤總額、凈利潤、貸款總額、存…

EPSON 任務同步 改寫

有時需要在多個任務執行之前來使它們同步。如果預先知道執行每項任務所需要的時間&#xff0c;它們就可以通過簡單地等待由最慢的任務產生的信號來實現同步。然而&#xff0c;如果不知道那個任務是最慢的&#xff0c;就需要使用一個更復雜的同步化機制&#xff0c;如下所示VAL …

線程池的簡單使用

創建指定線程數量的線程池 private static ExecutorService scheduledTaskFactoryExecutor null;private boolean isCancled false;private static class ThreadFactoryTest implements ThreadFactory { Overridepublic Thread newThread(Runnable r) { Thread threa…

異常--自定義異常類

為什么要調用父類構造器? http://blog.csdn.net/rockpk008/article/details/52951856 轉載于:https://www.cnblogs.com/dwj-ngu/p/6576382.html

利用ffmpeg來進行視頻解碼的完整示例代碼

&#xff08;轉&#xff09;利用ffmpeg來進行視頻解碼的完整示例代碼&#xff08;H.264&#xff09; Decode() { FILE * inpf; int nWrite; int i,p; int nalLen; unsigned char * Buf; int got_picture, consumed_bytes; unsigned char *DisplayBuf; Displ…

安卓觀看免費視頻

http://www.imooc.com/search/course?wordsAndroid%E6%94%BB%E5%9F%8E%E7%8B%AE%E7%AC%AC%E4%B8%80%E8%AF%BE&page3 http://www.imooc.com/course/list?candroid&src360onebox http://www.bilibili.com/video/av2788563/index_4.html http://www.imooc.com/course/pr…

EtherCAT 網站鏈接

http://www.ethercat.org.cn/cn.htm EtherCAT技術介紹 EtherCAT系統組成和工作原理 EtherCAT采用主從式結構&#xff0c;主站PC機采用標準的100Base-TX以太網卡&#xff0c;從站采用專用芯片。系統控制周期由主站發起&#xff0c;主站發出下行電報&#xff0c;電報的最大有效數…

IEC 6-1131/3的5種標準編程語言

用于開發控制系統和商業管理系統的TRACE MODE6編程工具面向不同領域的軟件工程師. TRACE MODE6包含的五種編程語言為&#xff1a;Techno SFC、Techno LD、Techno FBD、Techno ST和Techno IL. 這些語言是下列IEC 6-1131/3標準語言的擴展&#xff1a; SFC&#xff08;順序功能圖…

ngRx 官方示例分析 - 4.pages

Page 中通過構造函數注入 Store&#xff0c;基于 Store 進行數據操作。 注意 Component 使用了 changeDetection: ChangeDetectionStrategy.OnPush. OnPush means that the change detectors mode will be set to CheckOnce during hydration. /app/containers/collection-page…

用ffmpeg把yuv格式轉化為mpeg格式

http://blog.sina.com.cn/s/blog_5f5ad6a90100cs5k.html

方法:查詢MongoDB數據庫中最新一條數據(JAVA)

使用JAVA語言查詢MongoDB中某個數據庫某個集合的最新一條數據&#xff1a; MongoCollection<Document> cpu MongoClient.getDatabase("sysmgr").getCollection("cpu"); //獲取所需集合 Document dbo cpu.find().sort(descending("time"…