如何在被装饰函数中使用装饰器wrapper函数内的值?
问题解答
你当前的写法完全不可行,主要有两个问题:
- 装饰器的
wrapper函数需要接收json_file和csv_file两个参数,但被装饰的write_csv只定义了csv_file一个参数,调用时会直接触发参数不匹配的报错。 write_csv里的new_data = new_data属于无效代码:wrapper里的new_data是它的局部变量,和write_csv的作用域完全隔离,write_csv根本访问不到这个变量,运行时会抛出NameError。
下面给你几种可行的修改方案:
方案1:将new_data作为参数传递给被装饰函数
直接调整装饰器和被装饰函数的参数,让wrapper调用FUNCTION时把生成的new_data传进去:
def add_new_item(FUNCTION): def wrapper(json_file, csv_file): new_data = set_new_item() # 把new_data作为额外参数传给write_csv FUNCTION(csv_file, new_data) return new_data return wrapper @add_new_item def write_csv(csv_file, new_data): # 直接使用传入的new_data with open(csv_file, "a", newline="") as csv_file_obj: csv_writer = writer(csv_file_obj) csv_writer.writerow(new_data.values())
注:这里把文件对象的变量名改成csv_file_obj,避免和参数csv_file重名导致变量覆盖。
方案2:用可变对象实现闭包变量共享
如果不想修改函数参数,可以借助字典这类可变容器来共享数据:
def add_new_item(FUNCTION): def wrapper(json_file, csv_file): # 用字典存储new_data,可变对象能在嵌套函数中被访问修改 shared_data = {"new_data": set_new_item()} FUNCTION(csv_file, shared_data) return shared_data["new_data"] return wrapper @add_new_item def write_csv(csv_file, shared_data): new_data = shared_data["new_data"] with open(csv_file, "a", newline="") as csv_file_obj: csv_writer = writer(csv_file_obj) csv_writer.writerow(new_data.values())
方案3:让被装饰函数返回处理后的数据
如果逻辑允许,也可以让wrapper把new_data传给FUNCTION,再接收FUNCTION处理后的结果:
def add_new_item(FUNCTION): def wrapper(json_file, csv_file): new_data = set_new_item() # 接收write_csv处理后的结果 processed_data = FUNCTION(csv_file, new_data) return processed_data return wrapper @add_new_item def write_csv(csv_file, new_data): with open(csv_file, "a", newline="") as csv_file_obj: csv_writer = writer(csv_file_obj) csv_writer.writerow(new_data.values()) return new_data # 返回处理后的new_data
内容的提问来源于stack exchange,提问作者Zakhar Malinouski
相关产品推荐
相关产品推荐

