我发现 Python 3.7.2 的这种奇怪行为(我没有尝试过其他版本)。我创建了以下案例场景,希望能更好地了解正在发生的事情。我想编写一个 Object Inventory 类,包括一个记录器类,该类在柜台(例如每天)记录当前库存。然后我想使用记录器类来检索某一天的库存。这是代码:class Obj(): def __init__(self, parameter): self.par = parameterclass ObjInventory(): def __init__(self, object_list): self.list_of_objects = object_list self.counter = 0 self.logger = InventoryLogger() def increase_counter(self): self.logger.add_list_at_counter(self.counter, self.list_of_objects) self.counter += 1class InventoryLogger(): def __init__(self): self.dict_of_positions = {} def add_list_at_counter(self, counter, object_list): self.dict_of_positions[counter] = object_list def print_object_inventory_on_count(self, counter): object_list = self.dict_of_positions[counter] list_of_parameters = [object.par for object in object_list] print(list_of_parameters)Inventory = ObjInventory([])first_list_of_objects = [Obj(1), Obj(2), Obj(3)]Inventory.list_of_objects += first_list_of_objectsInventory.increase_counter()Inventory.logger.print_object_inventory_on_count(0)second_list_of_objects = [Obj(4), Obj(5), Obj(6)]Inventory.list_of_objects += second_list_of_objectsInventory.increase_counter()Inventory.logger.print_object_inventory_on_count(1)del Inventory.list_of_objects[2:4]Inventory.increase_counter()Inventory.logger.print_object_inventory_on_count(2)Inventory.logger.print_object_inventory_on_count(0)Inventory.logger.print_object_inventory_on_count(1)Inventory.logger.print_object_inventory_on_count(2)所以记录器打印只有在被直接调用后才起作用。如果我在稍后的步骤中调用 logger 函数,则所有字典条目都将等于最后一个条目。我通过以下方式修改 add_list_at_counter 函数找到了一种解决方法,这会导致所需的代码响应:def add_list_at_counter(self, counter, object_list): self.dict_of_positions[counter] = [] self.dict_of_positions[counter] += object_list特别是解决方法(我在几个小时后试图理解为什么代码不起作用)让我感到困惑。任何想法为什么第二个代码有效而第一个无效?或者它是某种错误?
1 回答
肥皂起泡泡
TA贡献1829条经验 获得超6个赞
您的问题是由以下事实引起的,即记录器中字典中的值的许多列表实际上都引用了相同的list_of_objects.
将其与此代码进行比较:
x = [1,2,3] # x refers to a list
y = x # y is another reference to the same list
x.append(4) # modify the list through x
print(y) # prints [1, 2, 3, 4], even though we accessed via y
您的代码正在做同样的事情,但不是像xand这样的简单变量,而是y通过属性和字典值(Inventory.list_of_objects以及Inventory.logger.dict_of_positions[counter]每个counter值)引用列表。
我不完全理解您的代码应该做什么,但我怀疑您可以通过更改increase_counter为list_of_objects使用list构造函数创建列表的副本来避免此问题:
def increase_counter(self):
self.logger.add_list_at_counter(self.counter, list(self.list_of_objects)) # new list
self.counter += 1
添加回答
举报
0/150
提交
取消