Why are these lists the same?
我不明白x和y是如何构成同一个列表的。我一直试图用print语句和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from collections import namedtuple, OrderedDict coordinates_2d=["x","y"] def virtual_container(virtual_container, objects_type): """Used to create a virtual object given a the type of container and what it holds. The object_type needs to only have normal values.""" if issubclass(virtual_container, list): class my_virtual_container_class: """This singleton class represents the container""" def __init__(self): #Define the default values __vals__=OrderedDict([(key,list()) for key in objects_type]) print(id(__vals__["x"]), id(__vals__["y"]))#ids are different: 12911896 12911968 #Then functions to access them d={key: lambda self: self.__vals__[key] for key in objects_type} d["__vals__"]=__vals__ #Construct a named tuple from this self.attr=type('attr_cl',(), d)() print(id(self.attr.x()), id(self.attr.y()))#ids are same: 32904544 32904544 #TODO: Define the operators __del__, setitem, getitem. Also append return my_virtual_container_class() #Nice method of handling coordinates coordinates=virtual_container(list, coordinates_2d) x=coordinates.attr.x() y=coordinates.attr.y() x.append(1) y.append(2) print(x, y)#Prints [1, 2] [1, 2] |
这一行有问题:
1 | d={key: lambda self: self.__vals__[key] for key in objects_type} |
lambda使用变量EDOCX1的值(0),但该值在调用lambda时已发生更改,因此所有lambda实际上都将对键使用相同的值。
这可以通过一个小技巧来解决:将键作为默认参数值传递给lambda:
1 | ... lambda self, key=key: self.__vals__[key] ... |
这样可以确保EDOCX1的值(0)与创建lambda时的值绑定在一起。
我认为下面这行应该是这样的(但不幸的是,我不能测试,因为我没有可用的python 3):
1 2 | # Then functions to access them d = dict((key, lambda self: self.__vals__[key]) for key in objects_type) |