簡體   English   中英

裝飾器運行錯誤:“UnboundLocalError:賦值前引用了局部變量‘count’”

[英]Decorator running error: "UnboundLocalError: local variable 'count' referenced before assignment"

我在兩個不同的裝飾器中創建了兩個變量,一個裝飾器運行良好,但另一個顯示錯誤。

def running_average(func):
    data = {'total': 0, 'count': 0}
    def wrapper(*args, **kwargs):
        print(data)
        val = func(*args, **kwargs)
        data['total'] += val
        data['count'] += 1
        print('Average of {} so far: {:.01f}'.format(func.__name__,
              data['total']/data['count']))
        return func(*args, **kwargs)
    return wrapper

@running_average
def foo(x):
    return x + 2

這個 foo 函數有效。

def countcalls(func):
    count = 0
    print(count)
    def wrapper(*args, **kwargs):
        print(count)
        count += 1
        print('# of calls: {}'.format(count))
        return func(*args, **kwargs)
    return wrapper

@countcalls
def boo(x):
    return x + 2

但是這個boo函數顯示錯誤: UnboundLocalError: local variable 'count' referenced before assignment

根據我的理解,這兩個函數遵循相同的模式。 在兩個裝飾器中,都在裝飾器中定義了一個變量,在包裝函數中使用了該變量。 但是,這個foo函數很好用,但是這個boo函數不起作用。 我想知道是什么原因?

不同的是,在第一個例子中,名稱data總是指向同一個對象; 它永遠不會被重新分配。 字典data所指的本身是變異(改變)的,但它始終是同一個對象。

相反,當您在第二個示例中執行count += 1時,會更改名稱count所指的值。 這使得count成為局部變量。 當解釋器看到這一點時,它注意到您在分配給它之前引用了局部變量count ,並失敗了。

解決方案是通過將其聲明nonlocal來告訴解釋器使用來自封閉范圍的count

def countcalls(func):
    count = 0
    print(count)
    def wrapper(*args, **kwargs):
        nonlocal
        print(count)
        count += 1
        print('# of calls: {}'.format(count))
        return func(*args, **kwargs)
    return wrapper

暫無
暫無

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

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