簡體   English   中英

python裝飾器從哪里獲取裝飾函數的參數

[英]Where does a python decorator get the arguments from the decorated function

我有以下代碼:

def foo(bar):
    def test(some_string):
        return 'Decorator test: '+bar(some_string)
    return test


def main():
    print(bar('test1'))


@foo
def bar(some_string):
    return some_string[:3]

我知道調用bar('test1)基本上是調用foo(bar('test1')) ,但是當我嘗試在foo的另一個函數之前打印some_string時,得到的some_string is not defined

def foo(bar):
    print(some_string)
    def test(some_string):
        return 'Decorator test: '+bar(some_string)
    return test
  1. test如何知道some_stringfoo不知道?
  2. 為什么必須返回test才能使裝飾器正常工作? 直接返回Decorator test: '+bar(some_string)不起作用,因為some_string

我知道調用bar('test1)基本上是調用foo(bar('test1'))

不,不是,您的理解不正確。 基本上是在打電話

foo(bar)('test')

@foo裝飾器語法告訴Python調用foo()傳入由bar命名的函數對象(並將結果分配回名稱bar )。

foo()裝飾器返回了一個新的函數對象:

def test(some_string):
    # ...
return test

因此, foo(bar)的結果是名為test函數對象( foo()裝飾器中的本地名稱)。 foo(bar)('test')因此稱為test('test')

如果要打印傳遞給test(..)的參數,請該函數內執行此操作:

def foo(bar):
    def test(some_string):
        print(some_string)
        return 'Decorator test: '+bar(some_string)
    return test

我知道調用bar('test1)基本上是調用foo(bar('test1'))

不,那是不正確的。

調用bar('test1')等效於

bar = foo(bar)
bar('test1')

為什么必須返回test才能使裝飾器正常工作? 直接返回裝飾器測試:'+ bar(some_string)不起作用,因為未定義some_string。

當你做

@decorator
def func():
    pass

Python將其轉換為

def func():
    pass

func = decorator(func)

如您所見,Python期望decorator返回一個函數。 這就是為什么必須從foo返回test以使bar正常工作的原因。 否則,將None分配給bar

>>> def foo(bar):
    def test(some_string):
        return 'Decorator test: '+bar(some_string)


>>> @foo
def bar(some_string):
    return some_string[:3]

>>> bar()
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    bar()
TypeError: 'NoneType' object is not callable

測試如何知道some_string而foo不知道?

只是因為在達到test之前不會創建some_string some_stringtest的參數,因此它僅存在於test的范圍內。 否則,將不存在名稱some_string ,因此,如果嘗試訪問它,則會收到NameError包括foo內部。

如果要print some_string的值,請在test內部test

def foo(bar):
    def test(some_string):
        print(some_string)
        return 'Decorator test: '+bar(some_string)
    return test

暫無
暫無

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

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