Skip to main content
 首页 » 编程设计

Python装饰器变量分数

2025年05月04日14unruledboy

我创建了一个简单的装饰器,它接收一个参数(使用函数而不是类),当发生某些事情时:添加一行代码会中断前一行的执行。

代码如下:

def my_decorator(sublabel): 
    def duration_wrapper(f): 
 
        print sublabel 
        # Uncommenting this code will break the previous line - why? 
        # if sublabel is None: 
        #     sublabel = f.func_name 
 
        def wrapped_function(*args, **kwargs): 
            return f(*args, **kwargs) 
 
        return wrapped_function 
 
    return duration_wrapper 
 
@my_decorator('me') 
def myf(): pass 
 
myf() 

取消注释这些代码行会导致此异常:

Traceback (most recent call last): 
  File "test.py", line 16, in <module> 
    @my_decorator('me') 
  File "test.py", line 4, in duration_wrapper 
    print sublabel 
UnboundLocalError: local variable 'sublabel' referenced before assignment 

谁能解释为什么取消注释这两行代码会破坏它?

请您参考如下方法:

装饰器是闭包,从封闭范围引用的封闭范围内的所有标签必须在封闭范围内保持静态。如果您希望封闭范围中的变量在封闭范围内可变,则需要将其包装在可变对象中,例如:

def my_decorator(sublabel): 
    sublabel = [sublabel] 
    def duration_wrapper(f): 
 
        print sublabel[0] 
        if sublabel[0] is None: 
            sublabel[0] = f.func_name 
 
        def wrapped_function(*args, **kwargs): 
            return f(*args, **kwargs) 
 
        return wrapped_function 
 
    return duration_wrapper 

正如@Bakuriu 在评论中指出的那样,Python 3 引入了 nonlocal 来消除此限制,您还可以将 sublabel 设置为全局来解决该问题,但是全局变量通常是个坏主意。