在本规范中:
results = []
for i in [1, 2, 3, 4]:
def inner(y):
return i
results.append(inner)
for i in results:
print i(None)
输出为“function inner at 0x107dea668”
如果i将i改为其他字母,例如:
^{pr2}$输出为“4”
回答
results = []
for i in [1, 2, 3, 4]:
def inner(y):
print "in inner:%s " % id(i)
return i
results.append(inner)
# i -> 4
for i in results:
# i -> func inner
print "i: %s" % i
print "in loop: %s " % id(i)
# func inner <===> A
# i == A -> return i -> return A, so when call funtion inner, will return itself
# print "call: %s" % i(None)
print "call: %s" % i(None)(None)(None)
print "------------------------------"
i:内部函数0x101344d70
环路:4315172208
在内线:4315172208
在内线:4315172208
在内线:4315172208
调用:函数内部位于0x101344d70
i:内部函数0x101344de8
环路:4315172328
在内线:4315172328
在内线:4315172328
在内线:4315172328
调用:函数内部位于0x101344de8
i:内部函数0x101344e60
环路:4315172448
在内线:4315172448
在内线:4315172448
在内线:4315172448
调用:函数内部位于0x101344e60
i:函数内部在0x101344ed8
环路:4315172568
在内线:4315172568
在内线:4315172568
在内线:4315172568
调用:函数内部位于0x101344ed8
您定义的
inner
函数包含一个引用全局变量i
的自由变量。在这样的例子中,这一点可能更清楚:它打印1和2
在您的第一个示例中,在调用
inner
时,i
有一个值,这个值是函数,因此在调用i
(即inner
)时打印的值。在在第二个例子中,在调用
inner
时,i
的值是4,因此当调用j
(即inner
)时,会打印出这个值。在一个明确的方法来表达您在这里可能想要的是使用一个部分求值的函数,正如另一个answer中建议的那样。另一种方法是使用封闭函数来创建闭包。像这样:
^{pr2}$它将打印1到4,大概是你想要的。在
Python中有时使用的一个小技巧是使用变量的默认值作为单元格来包含值:
也可以打印1到4。在
实际上,当你在结果中使用j时,变量i仍然是4,因为在第一个循环之后,i仍然是数字4
但是如果在结果中使用i,我指的是存储在结果中的函数。我是不会修好的,直到你开始叫它。正如@Jean fraçois Fabre所说,懒惰的评价。在
另外,如果您希望内部函数存储1-4循环时的每个i,则应将i存储在相关的范围内,使用部分函数
这将为您提供
^{pr2}$更有意义。在
在
inner
函数中返回的变量i
保持其值来自上次分配的上下文。在如果使用
inner
函数内的断点调试代码,则在调用函数之前选择上一帧/上下文(图中左下角)时,图片将变得更清晰。在当您使用
i
时,它被分配到第二个for
内,因此它将有一个函数作为其值(在图1中以黄色突出显示)。在现在,如果使用
j
,变量i
将保留上一个上下文中的最后一个值:列表上方的for
(图2)。在相关问题 更多 >
编程相关推荐