我有一些测试代码:
def num(num):
def deco(func):
def wrap(*args, **kwargs):
inputed_num = num
return func(*args, **kwargs)
return wrap
return deco
@num(5)
def test(a):
return a + inputed_num
print test(1)
运行此代码时,我收到错误显示'inputed_num'不是 defined
我的问题是:在wrap函数中,是不是func可以得到'inputed_num'的闭包?
无论如何,如果没有,我该怎样做才能实现我的目标: Initialize some value, and use this value directly in the main function.
想 .
4 回答
对不起,这不是装饰工作的方式 . 它们在最初定义函数后应用 . 到那时,为时已晚 .
当你写:
这相当于:
为了实现您的目标,让inputed_num成为第一个要测试的参数 . 然后,让装饰器传入该参数:
希望为你清除一切:-)
不,没有这样的封闭 . 函数可以关闭周围词汇上下文中存在的变量,而不是调用上下文中的变量 . 换句话说,如果您实际上在另一个函数中编写了一个函数,那么内部函数可以访问外部函数中的变量:
但函数永远不能访问调用它们的函数内的变量 .
一般来说,没有办法做你想要的,即在函数外部设置函数中的任意变量 . 最接近的是你可以在装饰器中使用
global inputed_num
来将inputed_num
指定为全局变量 . 然后test
将访问全局值 .但是,当然变量设置是全局的,因此多个并发使用(例如,递归)将不起作用 . (只是为了好玩,你也可以看到here这是一种非常神秘的方式来做到这一点,但是在现实环境中使用它太疯狂了 . )
正如@Raymond所说 - 在定义函数后应用装饰器 . 这意味着在编译函数体本身时,Pythn会看到
inputed_num
变量,并且当它捕获一个localy定义的变量时,它会生成代码以尝试将其作为全局变量访问它 .这意味着您可以在装饰器中对其进行解决:您的装饰器可以在函数globals()空间中设置具有所需名称的全局变量,然后调用该函数 . 它应该在单线程代码中可靠地工作:
和:
它不是应该使用装饰器的方式,我认为你的目的可能就是这样做的