【问题标题】:Instance variables in Python not as I assumedPython中的实例变量不像我想象的那样
【发布时间】:2012-06-10 17:44:42
【问题描述】:

我在 Python 中遇到了一个问题,我不敢相信会发现。见以下代码:

class Container(object):
    array = []

    def __init__(self):
        print self.array

for i in range(0, 5):
    container = Container()
    container.array.append('Test')
print 'Last Container:', container.array

输出是:

[]
['Test']
['Test', 'Test']
['Test', 'Test', 'Test']
['Test', 'Test', 'Test', 'Test']
Last Container: ['Test', 'Test', 'Test', 'Test', 'Test']

我认为Container 类在实例化时使用顶部的值进行初始化。为什么不是这样?

谢谢!

【问题讨论】:

标签: python arrays append instance instantiation


【解决方案1】:

class: 中的代码在创建类时执行,而不是在创建类实例时执行。这是一个更清楚地表明这一点的示例:

>>> class Test(object):
...     print "Test"
...     def __init__(self):
...         print "init"
...
Test
>>> t = Test()
init

请注意,“Test”是在创建类时打印的,而不是在我创建 Test 对象时打印的。

正如其他答案所指出的,如果您希望属性对于类的特定实例(而不是类的所有实例)是本地的,那么代码必须放在 __init__ 方法中:

def __init__(self):
    self.array = []

【讨论】:

    【解决方案2】:

    您直接放置在类定义中的任何属性都是类属性,因此Container.arrayContainer 的所有实例之间共享。

    如果您想要一个实例属性,请将self.array = [] 设置在__init__() 内:

        def __init__(self):
            self.array = []
            print self.array
    

    【讨论】:

      【解决方案3】:

      您应该像这样在 __init__ 中实例化列表:

      class Container(object):
      
          def __init__(self):
              self.array = []
              print self.array
      

      在类的顶层定义的类变量是在运行时创建的,所以如果它们是可变的——比如列表或字典——当你改变它们时就会遇到这个问题。 init 中设置的属性是在实例化类时创建的,这意味着您会为每个对象获得一个新列表。

      【讨论】:

      • 但我说self.。我认为您必须在类方法中提及类名或self.__class__.cls 才能访问类属性。为什么self. 有效?
      • @rynd: self. 也可用于访问类属性;事实上,这就是你获得方法的方式。
      • 更准确地说,如果在实例上找不到属性,则属性查找会继续到类(及其祖先)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 2010-11-05
      • 1970-01-01
      • 2020-11-14
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      相关资源
      最近更新 更多