为什么不同的变量名会得到不同的结果(python2.7)?

2024-09-26 22:45:33 发布

您现在位置:Python中文网/ 问答频道 /正文

在本规范中:

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


Tags: 函数innoneidforreturndefcall
3条回答

您定义的inner函数包含一个引用全局变量i的自由变量。在这样的例子中,这一点可能更清楚:

def inner(y):
    return i

i = 1
print inner(None)

i = 2
print inner(None)

它打印1和2

在您的第一个示例中,在调用inner时,i有一个值,这个值是函数,因此在调用i(即inner)时打印的值。在

在第二个例子中,在调用inner时,i的值是4,因此当调用j(即inner)时,会打印出这个值。在

一个明确的方法来表达您在这里可能想要的是使用一个部分求值的函数,正如另一个answer中建议的那样。另一种方法是使用封闭函数来创建闭包。像这样:

^{pr2}$

它将打印1到4,大概是你想要的。在

Python中有时使用的一个小技巧是使用变量的默认值作为单元格来包含值:

results = []
for i in [1, 2, 3, 4]:
    def inner(y, i = i):
        return i
    results.append(inner)

for i in results:
    print i(None)  

也可以打印1到4。在

实际上,当你在结果中使用j时,变量i仍然是4,因为在第一个循环之后,i仍然是数字4

但是如果在结果中使用i,我指的是存储在结果中的函数。我是不会修好的,直到你开始叫它。正如@Jean fraçois Fabre所说,懒惰的评价。在

另外,如果您希望内部函数存储1-4循环时的每个i,则应将i存储在相关的范围内,使用部分函数

from functools import partial

results = []
for i in [1, 2, 3, 4]:
    def inner(i, y):
        return i


    results.append(partial(inner, i))

for i in results:
    print(i(None))

这将为您提供

^{pr2}$

更有意义。在

inner函数中返回的变量i保持其值来自上次分配的上下文。在

如果使用inner函数内的断点调试代码,则在调用函数之前选择上一帧/上下文(图中左下角)时,图片将变得更清晰。在

当您使用i时,它被分配到第二个for内,因此它将有一个函数作为其值(在图1中以黄色突出显示)。在

Figure 1

现在,如果使用j,变量i将保留上一个上下文中的最后一个值:列表上方的for(图2)。在

Figure 2

相关问题 更多 >

    热门问题