如何使 python 函数将封闭变量绑定到值而不是名称
How to make python functions bind enclosing variable to value rather than to name
在 python 函数中,从封闭范围引用变量是完全合法的。这些变量指的是调用函数时它们拥有的任何值。所以,例如
x = 1 # unused
def foo(y):
return x+y
x=10
print(foo(1)) # prints 11
x=11
print(foo(1)) # prints 12
是否可以将变量 x
冻结为创建时 x
的任何值?也就是说,我希望 foo
中的 x
绑定到外部 x
的值而不是它的名称。基本上我想要的行为是
x = 1
def foo(y):
return 1+y # I'd rather not hard code the value of x here
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
我目前有一个可行的解决方案,但它的可读性不是很好,我认为可能会有更好的解决方案(也许是装饰器?)
我的解决方案
x = 1
def wrapper():
local_x = x
def foo(y):
return local_x+y
return foo
foo = wrapper()
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
您还可以利用默认参数:
x = 1
def foo(y, x=x):
return x + y
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
使用functools.partial应用第一个参数并得到一个接受一个参数的新函数。我选择不装饰 add 函数,因为它很通用,在其他地方也很有用。
from functools import partial
from operator import add # does same thing as your foo
x = 1
foo = partial(add, x)
print(foo(1)) # prints 2
x = 11
print(foo(1)) # prints 2
为了与您原来的解决方案保持一致,您还可以执行类似的操作。
def wrapper(localx):
def foo(y):
return localx + y
return foo
foo2 = wrapper(x)
print(foo2(1)) # prints 12
请注意,现在减少了对全局的依赖,您甚至可以将文字值传递给 wrapper
(例如 foo3 = wrapper(5)
)。
在 python 函数中,从封闭范围引用变量是完全合法的。这些变量指的是调用函数时它们拥有的任何值。所以,例如
x = 1 # unused
def foo(y):
return x+y
x=10
print(foo(1)) # prints 11
x=11
print(foo(1)) # prints 12
是否可以将变量 x
冻结为创建时 x
的任何值?也就是说,我希望 foo
中的 x
绑定到外部 x
的值而不是它的名称。基本上我想要的行为是
x = 1
def foo(y):
return 1+y # I'd rather not hard code the value of x here
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
我目前有一个可行的解决方案,但它的可读性不是很好,我认为可能会有更好的解决方案(也许是装饰器?)
我的解决方案
x = 1
def wrapper():
local_x = x
def foo(y):
return local_x+y
return foo
foo = wrapper()
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
您还可以利用默认参数:
x = 1
def foo(y, x=x):
return x + y
x=10
print(foo(1)) # prints 2
x=11
print(foo(1)) # prints 2
使用functools.partial应用第一个参数并得到一个接受一个参数的新函数。我选择不装饰 add 函数,因为它很通用,在其他地方也很有用。
from functools import partial
from operator import add # does same thing as your foo
x = 1
foo = partial(add, x)
print(foo(1)) # prints 2
x = 11
print(foo(1)) # prints 2
为了与您原来的解决方案保持一致,您还可以执行类似的操作。
def wrapper(localx):
def foo(y):
return localx + y
return foo
foo2 = wrapper(x)
print(foo2(1)) # prints 12
请注意,现在减少了对全局的依赖,您甚至可以将文字值传递给 wrapper
(例如 foo3 = wrapper(5)
)。