【问题标题】:Unexpected Python class variable [duplicate]意外的Python类变量[重复]
【发布时间】:2020-02-16 01:32:42
【问题描述】:

我在 Python 中遇到过几次这种行为,这有点令人费解。

class MyClass:
    def __init__(self, initial_data={}):
        self.data = initial_data

instance_a = MyClass()
instance_a.data['key1'] = 'val1'
print("instance_a.data:", instance_a.data)

instance_b = MyClass()
print("instance_b.data:", instance_b.data)

输出:

instance_a.data: {'key1': 'val1'}
instance_b.data: {'key1': 'val1'}

我希望 data 充当实例变量,但在这种情况下它看起来像一个类变量。

有谁确切地知道为什么会发生这种情况以及避免这种情况的最佳做法是什么?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    分配self.data = initial_data 时,您只需为对象initial_data 创建另一个新名称。

    您在此处未预料到的行为是由于默认参数 initial_data 在声明方法时仅被评估一次,而不是每次调用它时,因此所有使用它的实例实际上都使用相同的initial_data dict 对象,您可以使用不同的名称访问它,例如instance_a.datainstance_b.data 等。

    经典的解决方案是默认使用None,如下所示:

    class MyClass:
        def __init__(self, initial_data=None):
            if initial_data is None:
                initial_data = {}
            self.data = initial_data
    

    【讨论】:

      【解决方案2】:

      因为数据变量的id是一样的。 Python 中的函数是一流的对象,而不仅仅是一段代码。

      print(id(instance_a.data))
      # prints of object id
      
      print(id(instance_b.data))
      # prints the same object id
      

      这是因为构造函数的参数中的固定值。它不会为每个对象创建一个新字典。

      关于这样做:

      def __init__(self):
          self.data = {}
      

      你会得到不同的结果。

      在此处阅读更多信息:http://effbot.org/zone/default-values.htm

      希望这会有所帮助,祝你好运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        • 2012-12-23
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        • 2014-01-03
        • 1970-01-01
        相关资源
        最近更新 更多