理解Python闭包
我一直认为Python2.7函数指的是它们在中定义的范围。考虑下面的代码。为什么第二个输出不是“计算:sin” 有没有办法修改代码,使其按预期工作理解Python闭包,python,python-2.7,scope,closures,Python,Python 2.7,Scope,Closures,我一直认为Python2.7函数指的是它们在中定义的范围。考虑下面的代码。为什么第二个输出不是“计算:sin” 有没有办法修改代码,使其按预期工作 import math mymath = dict() for fun in ["sin", "cos"]: def _impl(val): print "calculating: %s" % fun return getattr(math, fun)(val) mymath[fun] = _imp
import math
mymath = dict()
for fun in ["sin", "cos"]:
def _impl(val):
print "calculating: %s" % fun
return getattr(math, fun)(val)
mymath[fun] = _impl
# calculating: cos
print mymath["cos"](math.pi)
# calculating: cos <- why?
print mymath["sin"](math.pi)
导入数学
mymath=dict()
为了在[“罪”,“因”]中获得乐趣:
def_impl(val):
打印“正在计算:%s”%s
返回getattr(数学、娱乐)(val)
我的数学[乐趣]=\u impl
#计算:cos
打印mymath[“cos”](math.pi)
#计算:cos调用函数时计算fun
的值
在您提供的示例中,fun
是一个全局变量,它的值在for
循环运行后为“cos”
我认为您希望在创建函数时替换fun
的值,但事实并非如此。函数在按预期方式运行时计算变量的值
它不是关于定义函数的名称空间,而是关于运行函数的名称空间
import math
mymath = dict()
for fun in ["sin", "cos"]:
def _impl(val):
print "calculating: %s" % fun
return getattr(math, fun)(val)
mymath[fun] = _impl
fun = 'tan'
# will print and calculate tan
print mymath["cos"](math.pi)
根据此代码(按照您的预期工作)
似乎不是函数定义的名称空间决定闭包的性质,而是所用变量的名称空间。
更多测试:
my = dict()
fun = ''
def makefun():
global fun #This line is switched on or off
fun = 'sin'
def _impl(x):
print fun, x
return _impl
test = makefun()
#gives sin 1
test(1)
fun = 'cos'
#gives sin 2 if line global fun is used
#gives cos 2 if line global fun is NOT used
test(2)
因此,正确的解释似乎是闭包保存了对其参数的引用,而不是一个值。我认为您试图让事情变得更难:
以下是使用闭包的方法:
import math
mymath = dict()
def funcmaker(fun):
print "creating %s function" % fun
def calculate(val):
print "calculating: %s" % fun
return getattr(math, fun)(val)
return calculate
print funcmaker("sin")(math.pi)
print funcmaker("cos")(math.pi)
上面的代码给出了以下结果:
creating sin function
calculating: sin
1.22464679915e-16
creating cos function
calculating: cos
-1.0
creating sin function
calculating: sin
1.22464679915e-16
creating cos function
calculating: cos
-1.0