下面是我的问题的一个最低限度的工作示例,其中我有一个包含fish对象数组的school对象,我希望每个fish都有基于其索引的属性。我所做的就是设置属性,然后打印出来,无论是在初始化过程中,还是在类完全实例化后。问题是,设置这些属性似乎对函数无效。此外,它的性能也因是否使用枚举而不同(我想了解这一点(。
在下面的代码中,输出显示我的学校对象中fish的'func'属性被覆盖,但'x'属性没有。
class Fish:
def __init__(self):
self.x = -1
self.func = lambda y: -1
class School:
def __init__(self):
self.fishList = [Fish() for i in range(2)]
for fishIndex, f in enumerate(self.fishList):
f.x = fishIndex
f.func = lambda y: fishIndex
print("No enumerate:")
for f in self.fishList:
print(f.x, f.func(0))
print("Enumerate")
for fishIndex, f in enumerate(self.fishList):
print(f.x, f.func(0))
mySchool = School()
print("-----------------------------------------")
print("No enumerate:")
for f in mySchool.fishList:
print(f.x, f.func(0))
print("Enumerate:")
for fishIndex, f in enumerate(mySchool.fishList):
print(f.x, f.func(0))
输出:
No enumerate:
0 1
1 1
Enumerate
0 0
1 1
-----------------------------------------
No enumerate:
0 1
1 1
Enumerate:
0 1
1 1
到目前为止,我已经追踪到这个问题源于我如何储存鱼。如果我将fish单独存储,而不是存储在数组中,那么函数将正确地持久存在。因此,这让我认为这是一个可变性/指针问题。但如果是这种情况,我预计"x"也不会正确地持续存在。
编辑:为了澄清,在输出的第一个";枚举";在虚线之前是我对所有输出的期望。
在func
的定义中,fishIndex
是一个自由变量。这意味着名称本身,而不是fishIndex
的当前值,是函数定义的一部分。
当函数被调用时,它将使用__init__
中定义的局部变量fishIndex
的当前值。
在__init__
中,当您在for
循环中将该变量用作索引变量时,该变量会发生变化。
在__init__
之外,fishIndex
仍然引用__init__
中定义的变量,即使该函数返回。我们说func
是定义它的范围的变量上的闭包。
在全局范围内重用循环中的名称fishIndex
不会影响func
的行为。