在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ Python修飾器
Python異常處理
Python循環(huán)
Python基本運(yùn)算符
Python網(wǎng)絡(luò)編程(Sockets)
Python可以開發(fā)哪些程序?
Python XML解析和處理
Python數(shù)字
Python函數(shù)
Python變量類型
Python os模塊方法
Python迭代器
Python安裝和環(huán)境配置
Python構(gòu)造函數(shù)
Python文件對象方法
Python日期和時(shí)間
Python的歷史
Python生成器
Python+MySQL數(shù)據(jù)庫操作(PyMySQL)
Python命令行參數(shù)
Python元組
Python發(fā)送郵件
Python列表
Python文件讀寫
Python教程
Python面向?qū)ο螅惡蛯ο螅?/span>
Python多線程編程
Python多重繼承
Python決策
Python是什么?
Python快速入門
Python繼承
Python字典
Python字符串
Python操作符重載
Python正則表達(dá)式
Python閉包
Python修飾器
Python功能特點(diǎn)
Python模塊

Python修飾器

裝飾器接收一個(gè)功能,添加一些功能并返回。 在本文中,您將學(xué)習(xí)如何創(chuàng)建裝飾器,以及為什么要使用裝飾器。

Python有一個(gè)有趣的功能,稱為裝飾器,以便為現(xiàn)有代碼添加功能。

這也稱為元編程,作為程序的一部分,嘗試在編譯時(shí)修改程序的另一部分。

學(xué)習(xí)裝修器之前需要了解什么?

為了了解裝飾器,我們首先在Python中了解一些基本的東西。

Python中的一切(是的,甚至是類)都是對象。 我們定義的名稱只是綁定到這些對象的標(biāo)識符。 函數(shù)也不例外,它們也是對象(帶有屬性)。 各種不同的名稱可以綁定到同一個(gè)功能對象。

看看下面一個(gè)示例 -

def first(msg):
    print(msg)    

first("Hello")

second = first
second("Hello")

當(dāng)運(yùn)行代碼時(shí),firstsecond函數(shù)都提供相同的輸出。 這里名稱firstsecond引用相同的函數(shù)對象。

函數(shù)可以作為參數(shù)傳遞給另一個(gè)函數(shù)。

如果您在Python中使用了map,filterreduce等功能,那么您就了解了。

將其他函數(shù)作為參數(shù)的函數(shù)也稱為高階函數(shù)。下面是這樣子的一個(gè)函數(shù)的例子。

def inc(x):
    return x + 1

def dec(x):
    return x - 1

def operate(func, x):
    result = func(x)
    return result

我們調(diào)用函數(shù)如下 -

>>> operate(inc,3)
4
>>> operate(dec,3)
2

此外,一個(gè)函數(shù)可以返回另一個(gè)函數(shù)。

def is_called():
    def is_returned():
        print("Hello")
    return is_returned

new = is_called()

#Outputs "Hello"
new()

這里,is_returned()是一個(gè)定義的嵌套函數(shù),在每次調(diào)用is_called()時(shí)返回。

回到裝飾器

實(shí)際上,實(shí)現(xiàn)特殊方法__call__()的任何對象都被稱為可調(diào)用。 因此,在最基本的意義上,裝飾器是可調(diào)用的,并且可以返回可調(diào)用。

基本上,裝飾器接收一個(gè)函數(shù),添加一些函數(shù)并返回。

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner

def ordinary():
    print("I am ordinary")

當(dāng)在shell中運(yùn)行以下代碼時(shí),如下 -

>>> ordinary()
I am ordinary

>>> # let's decorate this ordinary function
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

在上面的例子中,make_pretty()是一個(gè)裝飾器。 在分配步驟。

pretty = make_pretty(ordinary)

函數(shù)ordinary()得到了裝飾,返回函數(shù)的名字:pretty

可以看到裝飾函數(shù)為原始函數(shù)添加了一些新功能。這類似于包裝禮物。 裝飾器作為包裝紙。 裝飾物品的性質(zhì)(里面的實(shí)際禮物)不會(huì)改變。 但現(xiàn)在看起來很漂亮(因?yàn)檠b飾了)。

一般來說,我們裝飾一個(gè)函數(shù)并重新分配它,

ordinary = make_pretty(ordinary).

這是一個(gè)常見的結(jié)構(gòu),Python有一個(gè)簡化的語法。

可以使用@符號和裝飾器函數(shù)的名稱,并將其放在要裝飾的函數(shù)的定義之上。 例如,

@make_pretty
def ordinary():
    print("I am ordinary")

上面代碼相當(dāng)于 -

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

用參數(shù)裝飾函數(shù)

上面的裝飾器很簡單,只適用于沒有任何參數(shù)的函數(shù)。 如果有函數(shù)要接受如下的參數(shù)怎么辦?

def divide(a, b):
    return a/b

該函數(shù)有兩個(gè)參數(shù)ab。 我們知道,如果將b的值設(shè)置為0并傳遞那么是會(huì)出錯(cuò)的。

>>> divide(2,5)
0.4
>>> divide(2,0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero

現(xiàn)在使用一個(gè)裝飾器來檢查這個(gè)錯(cuò)誤。

def smart_divide(func):
   def inner(a,b):
      print("I am going to divide",a,"and",b)
      if b == 0:
         print("Whoops! cannot divide")
         return

      return func(a,b)
   return inner

@smart_divide
def divide(a,b):
    return a/b

如果發(fā)生錯(cuò)誤,這個(gè)新的實(shí)現(xiàn)將返回None

>>> divide(2,5)
I am going to divide 2 and 5
0.4

>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide

以這種方式就可以裝飾函數(shù)的參數(shù)了。

應(yīng)該會(huì)注意到,裝飾器中嵌套的inner()函數(shù)的參數(shù)與其裝飾的函數(shù)的參數(shù)是一樣的。 考慮到這一點(diǎn),現(xiàn)在可以讓一般裝飾器使用任何數(shù)量的參數(shù)。

在Python中,這個(gè)由function(* args,** kwargs)完成。 這樣,args將是位置參數(shù)的元組,kwargs將是關(guān)鍵字參數(shù)的字典。這樣的裝飾器的例子將是。

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner

在Python中鏈接裝飾器

多個(gè)裝飾器可以在Python中鏈接。

這就是說,一個(gè)函數(shù)可以用不同(或相同)裝飾器多次裝飾。只需將裝飾器放置在所需函數(shù)之上。

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner

def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner

@star
@percent
def printer(msg):
    print(msg)
printer("Hello")

執(zhí)行上面代碼,將輸出結(jié)果如下 -

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

以上語法,

@star
@percent
def printer(msg):
    print(msg)

相當(dāng)于以下 -

def printer(msg):
    print(msg)
printer = star(percent(printer))

鏈裝飾器的順序是重要的。 所以如果把順序顛倒了執(zhí)行結(jié)果就不一樣了,如下 -

@percent
@star
def printer(msg):
    print(msg)

執(zhí)行上面代碼,將輸出結(jié)果如下 -

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Hello
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

上一篇:Python操作符重載下一篇:Python教程