[TimLinux] Python 裝飾器

來源:互聯網
上載者:User

標籤:span   替換   臨時對象   fun   順序   cal   需要   name   python   

1. 裝飾器
  1. 一種文法格式,用於替換另外一個編碼風格,一種文法糖,通過文法結構明確標識出這樣一種文法。
  2. 自動在被裝飾對象尾部執行代碼(不使用裝飾器文法時,需要明確寫明的代碼)
  3. 被裝飾對象可以為函數、類,被裝飾對象為函數(則定義裝飾器為函數裝飾器),被裝飾對象為類(則定義裝飾器為類裝飾器)
  4. 裝飾器自身可以是函數、類。
2. 函數裝飾器函數裝飾器自動添加的代碼:
+----------------------------+----------------------------+| @decorator                 | def func():                || def func():                |     ....                   ||     ....                   | func = decorator(func)     |+----------------------------+----------------------------+| func()                     | decorator(func)()          |+----------------------------+----------------------------+
2.1. 裝飾器實現2.1.1. 函數方式實現
def decorator(F):    def tmp_F(*args_for_F):        這個函數內可以添加任你想執行的代碼。        F(*args_for_F)    return tmp_F  # 這個返回的是函數地址
2.1.2. 類方式實現
class decorator:    def __init__(self, F):        self.__func = F    def __call__(self, *args_for_F):        self.__func(*args_for_F)* 注意:這個方式,被裝飾對象如果是類中的函數,則不能正常工作,self的含義發生了變化。
3. 類裝飾器類裝飾器自動添加的代碼:
+----------------------------+----------------------------+| @decorator                 | class C:                   || class C:                   |     ....                   ||     ....                   | C = decorator(C)           |+----------------------------+----------------------------+| C()                        | decorator(C)()             |+----------------------------+----------------------------+
3.1. 裝飾器實現3.1.1. 函數方式實現
def decorator(cls):    class tmp_C:        def __init__(self, *args):              # cls(*args) --> 走的是被裝飾類的建立物件流程程,然後把返回的對象              # 存放在裝飾器類執行個體對象的一個靜態屬性中。            self.__instance = cls(*args)                # 最終訪問的是裝飾器類返回的執行個體,這個執行個體的屬性與被裝飾類執行個體的屬性是        # 一樣的。實現方法就是:屬性的傳遞。        def __getattr__(self, name):            return getattr(self.__instance, name)    return tmp_C@decoratorclass Person    def __init__(self, name, sex):        self.name = name        self.sex = sex                            # 末尾自動加上代碼:Person = decorator(Person)x = Person(‘Tim‘, ‘Male‘)   # x = Person(‘Tim‘, ‘Male‘) ---> Person已經
# 相當於tmp_C了,調用的是tmp_C.__init__print(x.name) # 調用的是 getattr(Person對象, name), 返回的是:‘Tim‘
 3.1.2. 類方式實現

各種實現都存在缺點,推薦使用函數方式。類方式主要特點是考慮,__init__ 會被decorator()調用,對象調用,obj(),會調用decorator.__call__方法。

4. 裝飾器嵌套
+-------------------------+-------------------------+| @A                      |                         || @B                      |                         || @C                      | fc = C(my_func)         || def my_func(..):        | fb = B(fc)              ||    ...                  | fa = A(fb)              |+-------------------------+-------------------------+| @A                      |                         || @B                      |                         || @C                      | cc = C(MyClass)         || class MyClass:          | bc = B(cc)              ||    ...                  | ac = A(bc)              |+-------------------------+-------------------------+
5. 裝飾器參數
+----------------------------+----------------------------+| @decorator(A,B)            | def func():                || def func():                |     ....                   ||     ....                   | f1 = decorator(A,B)        ||                            | func = f1(func)            |+----------------------------+----------------------------+| func()                     | decorator(A,B)(func)()     |+----------------------------+----------------------------+def decorator(A,B):    def f1(func):        def f2(*args_for_func):            ...        return f2    return f1
6. 總結裝飾器的核心:通過文法結構,隱藏在被裝飾函數之後,需要插入一段固定代碼的方法。
  1.  不帶參數的裝飾器:被裝飾對象同名對象 = 裝飾器(被裝飾對象),運行時順序:執行裝飾器內函數 -> 被裝飾函數
  2. 帶參數的裝飾器:
    • 被裝飾對象同名對象 = ( 裝飾器(裝飾器參數) )(被裝飾對象)
    • == 等價於 ==
    • 臨時對象 = 裝飾器(裝飾器參數)  # 會執行裝飾器函數,返回中間函數
    • 被裝飾對象同名對象 = 臨時對象( 被裝飾對象 )  # 會執行裝飾器內部的函數,並返回最底層一級封裝函數
  3. 嵌套裝飾器:
    • 被裝飾對象同名對象 = ( 最外層裝飾器( 中間裝飾器... ( 最內層裝飾器 ( 被裝飾對象 ) ) )
    • == 等價於 ==
    • 最內層裝飾後臨時對象 = 最內層裝飾器 ( 被裝飾對象 )  # 會執行裝飾器函數,並返回封裝函數
    • 中間裝飾後臨時對象 = 中間裝飾器 ( 最內層裝飾後臨時對象 )  # 會執行裝飾器函數,並返回封裝函數
    • 被裝飾對象同名對象 = 最外層裝飾器 ( 中間裝飾後臨時對象 )  # 會執行裝飾器函數,並返回封裝函數
    • 運行時順序:最外側 -> 中介層 -> 最內層 -> 被裝飾函數

[TimLinux] Python 裝飾器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.