为了账号安全,请及时绑定邮箱和手机立即绑定

包括记录器类的对象清单类会覆盖字典条目

包括记录器类的对象清单类会覆盖字典条目

qq_花开花谢_0 2021-10-26 15:35:41
我发现 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


查看完整回答
反对 回复 2021-10-26
  • 1 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信