簡體   English   中英

Python 裝飾器究竟是如何工作的?

[英]How exactly works Python decorator?

我絕對是 Python 新手(我來自 Java 和 C#)

我正在研究裝飾器主題。 所以我有以下例子:

# DECORATOR:
def my_decorator(func):
  def wrap_func():
    print('**************')
    func()
    print('**************')
  return wrap_func


@my_decorator
def hello():
  print('Hello World')

hello()

在我看來,這就是邏輯(但我不確定這一點:

我正在定義一個以另一個函數作為參數的my_decorator函數。 這個my_decorator函數將作為參數傳遞的函數包裝到一個wrap_func()函數中,該函數執行作為參數傳遞的函數。 另外這個wrap_func()函數可以在作為參數傳遞的函數執行前后執行一些額外的邏輯(它是裝飾原始函數。

要對解釋器說特定函數必須使用裝飾器,我必須在函數定義之前使用語法@decorator_name

所以在我的例子中:當我執行hello()調用時:Python 知道hello()函數必須由my_decorator裝飾器裝飾,所以它不是直接執行hello()函數而是執行my_decorator()函數傳遞hello ()引用作為參數。 因此它可以在hello()調用之前和之后添加額外的邏輯。

這個推理是正確的還是我錯過了什么?

我還有一個疑問:為什么裝飾器函數返回包裝我們裝飾邏輯的函數?

裝飾器只是函數調用的語法糖。

裝修

@my_decorator
def hello():
    print('Hello world')

相當於

def hello():
    print('Hello world')

hello = my_decorator(hello)

所以在這種情況下,使用裝飾器語法與直接定義以下函數是一樣的:

def hello():
    print('**************')
    print('Hello world')
    print('**************')

裝飾器創建一個函數,調用print('**************') ,然后調用原始函數,然后調用print('**************')再次。

如果你只打算裝飾一次函數,這顯然只是很多不必要的樣板。 但是,如果您要裝飾多個函數,則抽象是值得的:

# DECORATOR:
def my_decorator(func):
  def wrap_func():
    print('**************')
    func()
    print('**************')
  return wrap_func


@my_decorator
def hello():
  print('Hello World')

@my_decorator
def how_are_you():
  print("How are you doing?")

@my_decorator
def goodbye():
  print('Goodbye, world')

對比

def hello():
    print('**************')
    print('Hello world')
    print('**************')

def how_are_your():
    print('**************')
    print('How are you doing')
    print('**************')

def good_bye():
    print('**************')
    print('Goodbye world')
    print('**************')

特別是如果您后來決定用==============代替**************包裝每個輸出。

裝飾器只是一種語法糖。 這個:

@decorator
def func():
    pass

相當於:

def func():
    pass

func = decorator(func)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM