天天看點

python函數裝飾器python 函數裝飾器

注:讀本文章前請先了解閉包或者讀作者的python閉包附上連結python閉包

python 函數裝飾器

函數裝飾器 decorators

  • 定義:在不改變原函數的調用以及内部代碼的情況下,為其添加新功能的函數.
  • 文法:
    def 函數裝飾器名稱(func):
      		def 内嵌函數(*args,**kwargs)
      			需要添加的新功能
      			return func(*args, **kwargs)
      		return wrapper
      	
      	@ 函數裝飾器名稱
      	def 原函數名稱(參數):
      		函數體
      	原函數(參數)
               
  • 本質: 使用“@函數裝飾器名稱”修飾原函數,等同于建立與原函數名稱相同的變量,關聯内嵌函數;故調用原函數時執行内嵌函數。

    原函數名稱 = 函數裝飾器名稱(原函數名稱)

  • 裝飾器鍊:

    一個函數可以被多個裝飾器修飾,執行順序為從近到遠。

函數裝飾器的應用 :

需求:在兩個方法實作的功能基礎上,增加新功能(列印方法名稱)

def say_hello():
    print("hello")


def say_goodbye():
    print("goodbye")


say_hello()
say_goodbye()
# 輸出
'''
hello
goodbye
'''
           

方案1

缺點:代碼重複.

解決:提取列印方法名稱的功能

def say_hello():
    print(say_hello.__name__)
    print("hello")


def say_goodbye():
    print(say_goodbye.__name__)
    print("goodbye")


say_hello()
say_goodbye()
# 輸出
'''
say_hello
hello
say_goodbye
goodbye
'''

           

方案2

缺點:在兩個已有功能的内部,增加新功能,代碼可讀性差.

def print_func_name(func):
    print(func.__name__)


def say_hello():
    # print(say_hello.__name__)
    print_func_name(say_hello)
    print("hello")


def say_goodbye():
    # print(say_goodbye.__name__)
    print_func_name(say_goodbye)
    print("goodbye")


say_hello()
say_goodbye()
# 輸出:
'''
say_hello
hello
say_goodbye
goodbye
'''
           

方案示例(略…上正題)

使用函數裝飾器

包裝器适應所有的舊功能參數

定義者負責包裝函數,調用者隻負責調用

# 定義函數裝飾器
def print_func_name(func):
    # 包裝新舊功能
    def wrapper(*args, **kwargs):
        # 增加的新功能
        print(func.__name__)
        # 舊功能
        return func(*args, **kwargs)

    return wrapper  # 傳回包裝器
# 使用函數裝飾器    
@print_func_name    # say_hello = print_func_name(say_hello)
def say_hello(name):
    print(name, "hello")
    return "哈哈"


@print_func_name
def say_goodbye(name, age):
    print(age, name, "goodbye")

# # ---------以上是定義者--以下是調用者-----------------
print(say_hello("滅霸"))
say_goodbye("北極星女孩", 25)

# 輸出:
'''
say_hello
滅霸 hello
哈哈
say_goodbye
25 北極星女孩 goodbye
'''