我尝试了一个小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]
应该直接写实例变量吗?
答案 0 :(得分:2)
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
的内容,不会设置您实例上的属性。< / p>
请注意,这归结为:
>>> 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
值的引用的列表指定不同的值来更改属性