【问题标题】:Appending to array in object appends to all instances追加到对象中的数组追加到所有实例
【发布时间】:2019-04-19 22:29:49
【问题描述】:

我正在开发一款基于文本的游戏。我试图通过遵循所有惯例来使这尽可能有条理和专业。

我有一个 Map 类,如下所示:

import logging
#local imports
import Npc

class Map:
    def __init__(self, name, npcs = []):
        self.name = name
        connections = []
        if all(isinstance(item, Npc) for item in npcs):
            self.npcs = npcs
        else:
            raise Exception("An NPC was not an instance of NPC")


    def addConnection(self, connection):
        if(connection == self):
            return
        self.name = connection.name
        self.connections.append(connection)

我的 Main 类创建了这些地图的两个实例,分别名为 Forest 和 Village。 这段代码的重点是将村庄添加到森林的连接数组中:

village = Map("Village")
forest = Map("Forest")
forest.addConnection(village)

看起来很简单。但是由于某种原因,当forest.addConnection(village) 运行时,或者即使我运行forest.connections.append(village),地图实例“村庄”会被添加到森林和村庄的连接数组中。

根据调试器,forest.addConnection(village) 运行后, 我的两个对象如图所示:

village (Map)
|------> name="village"
|------> connections = [village]

forest (Map)
|------> name="forest"
|------> connections = [village]

为什么会这样?在我的代码中,我没有向村庄的连接数组添加任何内容。 Python中的面向对象编程有什么我不理解的吗?我应该创建继承/扩展 Map 类的村庄和森林类吗?

提前感谢所有帮助。

【问题讨论】:

  • 在对象创建过程中if all(isinstance(item, Map) for item in connections): 有什么用?您只是在检查一个空列表
  • 那是我忘记删除的旧代码。在我在 Map 的构造函数中有一个连接参数之前,但我决定使用函数将地图添加到连接数组中会更有意义。
  • 请提供造成问题的当前代码。这段代码看起来不错。猜你可能已经传递了一个类变量引用到 collection 字段之前
  • 现在您的实例甚至没有要附加到的 self.connections。发布一些实际运行并在运行时实际演示问题的内容。

标签: python python-3.x


【解决方案1】:

尽量避免调用构造函数作为函数的默认参数。 这就是您的问题的原因。

示例:

>>> class Map():
...     def __init__(self, a=list()): # do __init__(self, a=[]) produce same result
...             print(a)
...             a.append("hello")
... 
>>> b = Map()
[]
>>> b = Map()
['hello']
>>> b = Map()
['hello', 'hello']
>>> b = Map()
['hello', 'hello', 'hello']
>>> b = Map()
['hello', 'hello', 'hello', 'hello']

所以不想做:

def __init__(self, name, npcs = []):
    self.name = name
    ...

def __init__(self, name, npcs = None):
    if npcs is None:
        npcs = []
    self.name = name
    ...

【讨论】:

  • 是的,这是一个问题,但他没有在addConnection 方法中附加到npc 列表。
【解决方案2】:

发现问题。 @iElden 让我找对了地方。 在构造函数中,我是set connections = [],而不是self.connections = []

感谢您的回复!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 2016-12-03
    • 2021-09-09
    • 2019-05-28
    相关资源
    最近更新 更多