【问题标题】:Multiple instances of a class containing a list in python [duplicate]python中包含列表的类的多个实例[重复]
【发布时间】:2013-12-26 07:54:05
【问题描述】:

在 python 中运行以下代码时,我创建了一个类的 2 个对象,其中包含一个列表对象:

class Test():
    def run(self):
        obj1 = klasse("Werner")                       
        obj2 = klasse("Franz")  

        print obj1.name
        print obj2.name
        obj2.add_name("Thomas")
        print obj2.name

class klasse(object):
    name = [];

    def __init__(self, value):
        self.name.append(str(value))

    def add_name(self, value):
        self.name.append(str(value))

if __name__ == "__main__":
    Test().run()

这会在控制台中返回:

['Werner', 'Franz']
['Werner', 'Franz']
['Werner', 'Franz', 'Thomas']

问题:这似乎是两个创建的 klasse.objects 中的同一个列表对象。在每个创建的对象中隔离名称列表的解决方案是什么?

控制台输出应该是:

['Werner']
['Franz']
['Franz', 'Thomas']

【问题讨论】:

  • 你有一个 class 级别,而不是 instance 级别 name:修改 __init__ 使其具有 self.name = []。 .. 试图为此找到合适的骗子
  • 请正确缩进您的代码。这是 Python。

标签: python list object class-variables


【解决方案1】:

klasse 的实现应该如下所示:

class klasse(object):

    #  name = [] if this was the case, the name would be a class variable, 
    #  and all instances would share it

    def __init__(self, value):
        self.name = [] #  but now it is a separate for each instance
        self.add_name(value)

    def add_name(self, value):
        self.name.append(str(value))

编辑:采纳@Jon Clements 的建议。

【讨论】:

  • 如果要在初始化中使用add_name 则更好的设计... self.name = [] 然后self.add_name(value) 代替
【解决方案2】:

我几个小时前才遇到这个问题。

正如 cmets 所指出的,当您在类内但在类的方法外定义变量时,即是 类级别 变量。类级变量相当于其他语言中的静态变量。该类的所有实例共享的变量只有一个副本。有趣的是,当没有类的实例时,该变量也存在。使用您现有的代码库,尝试print klasse.name

如果您在类的方法内定义变量,则该变量对于定义它的类的实例是唯一的。要获得想要的效果,您需要在__init__ 方法中创建并初始化self.name。这将在类的每个实例中创建一个唯一的变量实例。

附带说明,在 python 和大多数其他 OO 语言中,类名大写被认为是最佳实践。

【讨论】:

    【解决方案3】:

    如果您不添加self.,则该变量将是类变量,而不是实例变量,这意味着对于每个对象,值都是相同的。对于这种情况,要使 name 成为实例变量,您需要执行以下操作:

    self.name = []
    

    如果这在您的测试中不明显,您不能在函数之外声明 self.myVariable

    【讨论】:

    • 严格遵循,这是行不通的:你不能在类中声明self.name outside 函数,对吗?它必须在__init__ 或某个函数中。
    • @Joël 认为这是暗示...
    • 好吧,我认为这不是那么简单:您必须在前面加上 才能在正确的位置声明;)
    • @Joël 可能不是很直观,但是输入一行代码就可以看出它不起作用。
    • @volcano 那是错误的。它不必以类名开头。
    【解决方案4】:

    在类 Klasse 中,名称变量是类级别的变量,因此在创建该类的新实例之前首先检查名称列表是否为空。如果不为空,则在 init() 中将其设为空,因为每次创建该类的实例时都会调用此函数。

    >>> class klasse(object):
    ...     name = []
    ...     def __init__(self, value):
    ...         if self.name:
    ...             self.name = []
    ...         self.name = [value]
    ...     def add_name(self, value):
    ...         self.name.append(str(value))
    ...     
    >>> class Test():
    ...     def run(self):
    ...         obj1 = klasse("Werner")
    ...         obj2 = klasse("Franz")
    ... 
    ...         print obj1.name
    ...         print obj2.name
    ...         obj2.add_name("Thomas")
    ...         print obj2.name
    ...     
    
    >>> Test().run()
    ['Werner']
    ['Franz']
    ['Franz', 'Thomas']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 2019-04-27
      • 1970-01-01
      • 2021-02-19
      • 1970-01-01
      • 2015-04-05
      • 2019-12-09
      相关资源
      最近更新 更多