我最近刚与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的新“干净”实例,并在添加前后打印字典。
do_something_with_aX()
错误(如果您尚未弄清楚):
>>> 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的第二次初始化中,字典不是空的,而是从最后一次初始化的内容开始,依此类推。我希望他们开始“新鲜”。
解决此“错误”的原因显然是添加了:
self.dict1 = {}
在__init__类A的构造函数中。但是,这使我感到奇怪:
__init__
编辑:按照答案,我现在了解到,通过声明一个数据成员,而不是在__init__self.dict1或其他地方引用它,我实际上是在C ++ / Java中定义一个静态数据成员。通过将其称为self.dict1,我将其设为“实例绑定”。
您一直称其为错误的是Python类的已记录的标准行为。
__init__像最初那样在外部声明dict就是在声明类级变量。最初它只会创建一次,每当您创建新对象时,它都会重复使用此相同的字典。要创建实例变量,请使用selfin声明它们__init__;就这么简单。
self