我尝试了一个小的trafficlight
实现并得到了以下代码:
def __init__(...):
...
self.redLight = Light(color = "red", master = self.frame)
self.redLight.place(x = 10, y = 10)
self.yellowLight = Light(color = "yellow", master = self.frame)
self.yellowLight.place(x = 10, y = 40)
self.greenLight = Light(color = "green", master = self.frame)
self.greenLight.place(x = 10, y = 70)
...
我感到无聊,并尝试在循环中定义这个相当冗余的代码:
def __init__(...):
...
self.redLight = None
self.yellowLight = None
self.greenLight = None
for l in [[self.redLight, "red", 10],
[self.yellowLight, "yellow", 40],
[self.greenLight, "green", 70]]:
l[0] = Light(color = l[1], master = self.frame)
l[0].place(x = 10, y = l[2])
...
我的理解是,它的作用与第一个代码示例完全相同,但事实证明,它不写入实例变量。当我在调试器中查看代码时,l[0]
对象是一个 Light-object...
python不是按引用调用吗,所以l[0]
应该直接写入实例变量吗?
最佳答案
def __init__(self):
for l in [['redLight', "red", 10],
['yellowLight', "yellow", 40],
['greenLight', "green", 70]]:
setattr(self, l[0], Light(color=l[1], master=self.frame))
getattr(self, l[0]).place(x=10, y=l[2])
因为正如分配给l[0]
的评论中提到的只是更改局部变量 l
的内容它不会设置您的实例的属性。
请注意,这可以归结为:
>>> a = 1
>>> b = a
>>> b = 2 # assigning a new value to "b" doesn't change "a"!
>>> a
1
或者:
>>> a = 1
>>> b = [a]
>>> b[0] = 2 # won't change "a".
>>> a
1
因此,虽然您可以通过分配给 self.redLight
来更改属性并不意味着您可以通过向包含值 self.redLight
的引用的列表分配不同的值来更改属性。 .
关于python - 在循环中创建实例变量返回 None 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46146278/