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

我发现 Python 3.7.2 的这种奇怪行为(我没有尝试过其他版本)。我创建了以下案例场景,希望能更好地了解正在发生的事情。


我想编写一个 Object Inventory 类,包括一个记录器类,该类在柜台(例如每天)记录当前库存。然后我想使用记录器类来检索某一天的库存。


这是代码:


class Obj():

    def __init__(self, parameter):

        self.par = parameter



class 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 += 1



class 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_objects

Inventory.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_objects

Inventory.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

特别是解决方法(我在几个小时后试图理解为什么代码不起作用)让我感到困惑。任何想法为什么第二个代码有效而第一个无效?或者它是某种错误?


qq_花开花谢_0
浏览 137回答 1
1回答

肥皂起泡泡

您的问题是由以下事实引起的,即记录器中字典中的值的许多列表实际上都引用了相同的list_of_objects.将其与此代码进行比较:x = [1,2,3]      # x refers to a listy = x            # y is another reference to the same listx.append(4)      # modify the list through xprint(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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python