Python 类成员初始化

标签 python class initialization

我最近刚刚与 Python 中的一个错误作斗争。这是那些愚蠢的新手错误之一,但它让我想到了 Python 的机制(我是一名长期 C++ 程序员,对 Python 不熟悉)。我将列出错误代码并解释我做了什么来修复它,然后我有几个问题......

场景:我有一个名为 A 的类,它有一个字典数据成员,下面是它的代码(当然这是简化):

class A:
    dict1={}

    def add_stuff_to_1(self, k, v):
        self.dict1[k]=v

    def print_stuff(self):
        print(self.dict1)

使用此代码的类是B类:

class B:

    def do_something_with_a1(self):
        a_instance = A()
        a_instance.print_stuff()        
        a_instance.add_stuff_to_1('a', 1)
        a_instance.add_stuff_to_1('b', 2)    
        a_instance.print_stuff()

    def do_something_with_a2(self):
        a_instance = A()    
        a_instance.print_stuff()            
        a_instance.add_stuff_to_1('c', 1)
        a_instance.add_stuff_to_1('d', 2)    
        a_instance.print_stuff()

    def do_something_with_a3(self):
        a_instance = A()    
        a_instance.print_stuff()            
        a_instance.add_stuff_to_1('e', 1)
        a_instance.add_stuff_to_1('f', 2)    
        a_instance.print_stuff()

    def __init__(self):
        self.do_something_with_a1()
        print("---")
        self.do_something_with_a2()
        print("---")
        self.do_something_with_a3()

请注意,每次调用 do_something_with_aX() 都会初始化一个新的“干净”类 A 实例,并在添加前后打印字典。

错误(如果您还没有弄清楚):

>>> b_instance = B()
{}
{'a': 1, 'b': 2}
---
{'a': 1, 'b': 2}
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
---
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
{'a': 1, 'c': 1, 'b': 2, 'e': 1, 'd': 2, 'f': 2}

在类A的第二次初始化中,字典不为空,而是以最后一次初始化的内容开始,以此类推。我希望他们能够“重新开始”。

解决这个“bug”的显然是添加:

self.dict1 = {}

在 A 类的 __init__ 构造函数中。然而,这让我想知道:

  1. 在 dict1 的声明处(A 类的第一行)初始化“dict1 = {}”是什么意思?没意义?
  2. 导致从上次初始化复制引用的实例化机制是什么?
  3. 如果我在构造函数(或任何其他数据成员)中添加“self.dict1 = {}”,它如何不影响先前初始化实例的字典成员?

编辑:按照我现在的答案,通过声明一个数据成员而不是在 __init__ 或其他地方将其引用为 self.dict1,我实际上是在定义 C++/Java 是一个静态数据成员。通过将其称为 self.dict1 我将其设为“实例绑定(bind)”。

最佳答案

你一直提到的错误是 documented , Python 类的标准行为。

像您最初所做的那样在 __init__ 之外声明一个字典就是声明一个类级变量。它一开始只创建一次,每当您创建新对象时,它都会重用相同的字典。要创建实例变量,请在 __init__ 中使用 self 声明它们;就这么简单。

关于Python 类成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/867219/

相关文章:

java - Java中初始化一个Vector对象,总是不对

c++ - 如何在完成其他一些任务后在 CTOR 中初始化对象?

Python从另一个包获取模块引用,知道包和模块名称

java - 如何理解 "Every Class object contains a reference to the ClassLoader that defined it. "?

javascript - 如何删除 jQuery 中特定表格行下方的所有表格行

C# 需要对新约束进行解释 (new T(...))

java - 在for语句的初始化中可以初始化多少个变量?

Python矩阵乘法,

python - 斯坦福 CoreNLP tokenize.whitespace 属性不适用于中文

python - 安装 PySimulator