裝飾器語法糖運用

裝飾器語法糖運用

  • 前言:函數名是一個特性的變量,可以作為容器的元素,也可以作為函數的參數,也可以當做返回值。

  • 閉包定義:

    • 內層函數對外層函數(非全局)變量的引用,這個內層函數就可以成為閉包

    • 在Python中我們用__closure__來檢查函數是否是閉包

    • def func1():name = '張三'def func2():print(name)  # 能夠訪問到外層作用域的變量func2()print(func2.__closure__)  # (<cell at 0x1036c7438: str object at 0x10389d088>,)func1()
      print(func1.__closure__)  # None
  • 裝飾器

    • 前言:軟件設計原則:開閉原則,又稱開放封閉原則

      • 指對擴展代碼的功能是開放的,但對修改源代碼是封閉的,
    • def create_people():print('女媧真厲害,捏個泥吹口氣就成了人!')def a(func):def b():print('灑點水')func()return bret = a(create_people)
      ret()
    • 通過裝飾器語法等同于

    • def a(func):def b():print('灑點水')func()return b@a  # 裝飾器語法糖的作用就是上述函數ret()
      def create_people():print('女媧真厲害,捏個泥吹口氣就成了人!')create_people()
  • 裝飾帶返回值的函數,即return出被裝飾函數的執行結果

    • def foo(func):  # 接收的參數是一個函數名def bar():  # 定義一個內層函數print("這里是新功能...")  # 新功能r = func()  # 在內存函數中拿到被裝飾函數的結果return r  # 返回被裝飾函數的執行結果return bar# 定義一個有返回值的函數
      @foo
      def f1():return '嘿嘿嘿'# 調用被裝飾函數
      ret = f1()  # 調用被裝飾函數并拿到結果
      print(ret)
  • 裝飾帶參數的函數

    • def func1(func):              # 接收的參數為一個函數名def inner(*args, **kwargs):     # 這里需要定義和被裝飾函數相同的參數print("新功能")                # 新功能ret = func(*args, **kwargs)     #被裝飾的函數和參數print("新功能")         return retreturn inner# 定義一個需要倆個參數的函數
      @func1
      def func(a, b):return a + bret = func(3, 5)
      print(ret)
  • 帶參數的裝飾器 即在裝飾器外在寫一層函數,從而使其帶參數

    • def d(a=None):        # 定義一個外層函數,給裝飾器傳參數def func1(func):  # 接收的是一個函數名def inner(*args, **kwargs): # 被裝飾的函數,和參數if a:print(f"歡迎來到{a}")   #添加新功能else:print("歡迎來到王者榮耀")  func(*args, **kwargs)return innerreturn func1# @d("英雄聯盟")
      # def func(st):
      #     print(st)
      # func("敵軍還有三十秒到達戰場")# 歡迎來到英雄聯盟# 敵軍還有三十秒到達戰場@d()
      def func(st):print(st)
      func("敵軍還有三十秒到達戰場")
      # 歡迎來到王者榮耀
      # 敵軍還有三十秒到達戰場
  • 裝飾器修復技術

    • 定義:被裝飾的函數最終都會失去本來的__doc__等信息, Python給我們提供了一個修復被裝飾函數的工具。

    • from functools import wraps    #導入
      print(f1.__doc__)
      print(f1.__name__)
  • 多個裝飾器裝飾同一函數

    • from functools import wrapsdef wrapper2(func):@wraps(func)def inner(*args, **kwargs):r = func(*args, **kwargs)return f"<2>{r}</2>"return innerdef wrapper1(func):@wraps(func)def inner(*args, **kwargs):r = func(*args, **kwargs)return f"<1>{r}</1>"return inner@wrapper2
      @wrapper1
      def func(a):return aprint(func("Hello World!!"))  #<2><1>Hello World!!</1></2>
    • def foo1(func):print("d1")def inner1():print("inner1")return "<i>{}</i>".format(func())return inner1def foo2(func):print("d2")def inner2():print("inner2")return "<b>{}</b>".format(func())return inner2@foo1
      @foo2
      def f1():return "Hello Andy"# f1 = foo2(f1)  ==> print("d2") ==> f1 = inner2
      # f1 = foo1(f1)  ==> print("d1") ==> f1 = foo1(inner2) ==> inner1ret = f1()  # 調用f1() ==> inner1()  ==> <i>inner2()</i>  ==> <i><b>inner1()</b></i> ==> <i><b>Hello Andy</b></i>
      print(ret)
  • 類裝飾器

    • class D(object):def __init__(self, a=None):self.a = aself.mode = "裝飾"def __call__(self, *args, **kwargs):if self.mode == "裝飾":self.func = args[0]  # 默認第一個參數是被裝飾的函數self.mode = "調用"return self# 當self.mode == "調用"時,執行下面的代碼(也就是調用使用類裝飾的函數時執行)if self.a:print("歡迎來到{}頁面。".format(self.a))else:print("歡迎來到首頁。")self.func(*args, **kwargs)@D()
      def index(name):print("Hello {}.".format(name))@D("電影")
      def movie(name):print("Hello {}.".format(name))if __name__ == '__main__':index('張三')movie('張三')
  • 裝飾類

    • # 定義一個類裝飾器
      class D(object):def __call__(self, cls):class Inner(cls):# 重寫被裝飾類的f方法def f(self):print('Hello 張三.')return Inner@D()
      class C(object):  # 被裝飾的類# 有一個實例方法def f(self):print("Hello world.")if __name__ == '__main__':c = C()c.f()

轉載于:https://www.cnblogs.com/yuncong/p/9886555.html

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

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

相關文章

fb 4.7英文版 顯示行數

窗口&#xff08;window&#xff09;首選項&#xff08;Preference&#xff09;—>常規&#xff08;General&#xff09;—>編輯器&#xff08;Editors&#xff09;—>文本編輯器&#xff08;Text Editors&#xff09;—>“顯示行號”&#xff08;Show line number…

集市中迷失的一代:FreeBSD核心開發者反思開源軟件質量

摘要&#xff1a;本文作者Poul-Henning Kamp (phkFreeBSD.org) &#xff0c;26年的計算機程序員&#xff0c;他編寫的軟件以底層構建塊的形式廣泛被開源和商業產品采用。講述作者在看完《設計原本》這本書后所引發的共鳴&#xff01; 13年前&#xff0c;新興的草根開源軟件運動…

點擊表格彈窗獲取另外一套數據之后,原表格相關數據的調用

用H5新屬性&#xff0c;data-*&#xff0c; $獲取方式&#xff1a; 待續。。。。。。。 轉載于:https://www.cnblogs.com/He-tao-yuan/p/9888316.html

谷歌瀏覽器如何如何禁用彈出窗口阻止程序

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在工具欄上使用 Google Chrome 菜單。工具欄上的菜單位于瀏覽器右上角。 選擇“設置”。 在頁面底端找到并點擊“顯示高級設置”。 在“隱…

Python 3 入門,看這篇就夠了

文章目錄 簡介基礎語法運算符變量數據類型流程控制迭代器生成器函數 自定義函數參數傳遞 可更改與不可更改對象參數匿名函數變量作用域模塊面向對象錯誤和異常文件操作序列化命名規范參考資料簡介 Python 是一種高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。Pyt…

面試經歷(二)

前面說到用數據庫中的鎖機制對并發事務進行控制&#xff0c;這節來說說事務方法和事務方法發生嵌套調用時事務如何進行傳播。例如&#xff1a;方法可能繼續在現有事務中運行&#xff0c;也可能開啟一個新事務&#xff0c;并在自己的事務中運行。例如&#xff1a;方法可能繼續在…

最有價值的編程忠告

摘要&#xff1a;本文是來自貝爾實驗室Plan 9操作系統的創始人Rob Pike給大家分享的編程忠告&#xff01;Rob Pike&#xff0c;目前谷歌公司最著名的軟件工程師之一&#xff0c;曾是貝爾實驗室Unix開發團隊成員&#xff0c;締造Go語言和Limbo語言的核心人物。 Rob Pike&#xf…

Column count doesn't match value count at row 1 原因

mysql 提示 &#xff1a; Column count doesnt match value count at row 1錯誤&#xff0c;SQL語句中列的個數和值的個數不等&#xff0c; 如&#xff1a; insert into table1 (field1,field2) values(值1&#xff0c;值2&#xff0c;值3 ) 列只有2個&#xff0c;值 卻有3個…

MarkDowm快捷鍵大全

文章目錄一&#xff1a;菜單欄二&#xff1a;文件三&#xff1a;編輯四&#xff1a;段落五&#xff1a;格式六&#xff1a;視圖一&#xff1a;菜單欄 文件&#xff1a;altF 編輯&#xff1a;altE 段落&#xff1a;altP 格式&#xff1a;altO 視圖&#xff1a;altV 主題&#x…

Kinect2.0-空間長度測量

1. 鼠標左鍵按下選擇起點&#xff0c;拖動鼠標&#xff0c;左鍵放開&#xff0c;確定終點。 實現效果1實現效果22. 在linux下使用libfreenect2開源多平臺驅動來獲取kinect2.0的傳感器信息&#xff0c;得到深度信息&#xff0c;并通過libfreenect2提供的getPointXYZ函數&#xf…

帶數據庫的智能合約

編寫使用數據庫的智能合約 前面一直在搗鼓EOS網絡搭建的相關東西。然而今天比較不走運的是&#xff0c;興致勃勃的把源碼版本升到4.0&#xff0c;在編譯的時候如我所猜想的出現了一系列問題&#xff0c;正一籌莫展的時候&#xff0c;導師突然問了我一個關于合約如何操作數據庫的…

沒有完美的軟件:編程永遠不容易

摘要&#xff1a;很多人想用十全十美來修飾一樣東西&#xff0c;比如軟件&#xff0c;對于客戶來說&#xff0c;當然希望他們的軟件能做到完美。雖然很多專家說利用一些規范可以讓軟件達到更好&#xff01;但是在現實開發中&#xff0c;真的會有那么完美的軟件嗎&#xff1f; 最…

Eclipse斷點調試出現Source not found

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我的情況是和網上說的都不一樣&#xff0c;我真的也沒有想到這么坑&#xff0c; 我居然無意寫了一個死循環&#xff0c;dao/mapper調sql…

Memory Compression這到底是個什么東西?

Memory Compression這到底是個什么東西&#xff1f; Memory Compression這個進程&#xff0c;經過我的查詢說是內存壓縮功能&#xff0c;作用是壓縮內存讓內存占用更低&#xff0c;但是為什么這個進程瘋狂占用我的內存&#xff0c;我用的Win10 8G&#xff0c;通過資源監視器查看…

MySQL 5.6 for Windows 解壓縮版配置安裝

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 MySQL是一個小巧玲瓏但功能強大的數據庫&#xff0c;目前十分流行。但是官網給出的安裝包有兩種格式&#xff0c;一個是msi格式&#xf…

safari的一些問題

1、圖片過大時&#xff0c;在webview中是不會加載顯示的。2、如果是通過一個地址返回的base64數據給image&#xff0c;記住要在后臺進行base64_decode解析數據&#xff0c;這樣才是真實的圖片數據&#xff0c;后臺保存數據的時候不要保存"data:image/png;base64,"這一…

代碼審查“思維導圖”

摘要&#xff1a;隨著人們對軟件質量要求的不斷提高&#xff0c;軟件開發的每一個環節都應該得到十足的重視&#xff0c;俗話說&#xff1a;“細節決定成敗”&#xff0c;就此&#xff0c;本文提供了一個代碼審查“思維導圖”&#xff0c;希望對所有碼農們有所幫助。 代碼審查&…

thinkCMF----導航高亮顯示

導航高亮顯示&#xff0c;有多種方法&#xff0c;這里給出一個簡單的表示下&#xff1a; <a href"__ROOT__"><span class"text db">網站首頁</span><span class"eng db">HOME</span> </a> …

The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 tomcat啟動報務后訪問頁面報錯&#xff1a; org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/co…

優秀程序員和一般程序員差別在哪?

摘要&#xff1a;在這個世界上有兩種程序員&#xff1a;Day Programmers&#xff08;白班程序員&#xff09;和Night Programmers&#xff08;夜貓子程序員&#xff09;&#xff0c;你知道優秀程序員和一般程序員有哪些差別嗎&#xff1f;你又是哪一類型的呢&#xff1f;俗話說…