【发布时间】:2023-04-08 04:58:01
【问题描述】:
我最近刚刚与 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__ 构造函数中。然而,这让我想知道:
- 在 dict1 的声明点(A 类的第一行)初始化“dict1 = {}”是什么意思?没意义?
- 导致复制上次初始化的引用的实例化机制是什么?
- 如果我在构造函数(或任何其他数据成员)中添加“self.dict1 = {}”,它如何不影响先前初始化实例的字典成员?
编辑:按照答案,我现在明白,通过声明一个数据成员而不是在 __init__ 或其他地方将其引用为 self.dict1,我实际上是在定义 C++/Java 中所谓的静态数据成员.通过将其称为 self.dict1 我将其设为“实例绑定”。
【问题讨论】:
-
你应该使用新式类,派生自对象。
-
A 类没有
__init__()。您是否故意没有,这相当于一个空的def __init__(self): pass,因此它当然没有数据成员?如果没有,请修复您的代码。
标签: python class initialization