Python继承、超级调用顺序和AttributeError
我不知道继承的类属性是如何初始化的。我在我认为定义良好的子属性上得到了AttributeError 我注意到在定义之后交换超级调用到父级的顺序不会产生错误,但我不理解为什么 我无法在不使用进程的情况下重现该错误,我也可以发布测试代码,但我认为这已经足够长了,似乎调用super的顺序并不重要 编辑:可能是因为在定义计数器之前运行一个进程导致了异常,但如果我使用线程而不是进程,则不会出现问题 我可能遗漏了一些关于初始值设定项是如何工作的,或者做错了什么 为什么会出现属性错误? 为什么交换两行可以解决或掩盖问题? 为什么使用线程而不是进程不会发生此问题? 我正在使用下面的代码 谢谢你的帮助 以下是重现该问题的代码。我尽了最大努力使它独立Python继承、超级调用顺序和AttributeError,python,inheritance,attributeerror,python-multiprocessing,Python,Inheritance,Attributeerror,Python Multiprocessing,我不知道继承的类属性是如何初始化的。我在我认为定义良好的子属性上得到了AttributeError 我注意到在定义之后交换超级调用到父级的顺序不会产生错误,但我不理解为什么 我无法在不使用进程的情况下重现该错误,我也可以发布测试代码,但我认为这已经足够长了,似乎调用super的顺序并不重要 编辑:可能是因为在定义计数器之前运行一个进程导致了异常,但如果我使用线程而不是进程,则不会出现问题 我可能遗漏了一些关于初始值设定项是如何工作的,或者做错了什么 为什么会出现属性错误? 为什么交换两行可以解决
from multiprocessing import Process
from multiprocessing import Queue
class Parent(object):
def __init__(self):
self._stuff_queue = Queue()
self._process = Process(target=self._do_something)
self._process.start()
def _do_something(self):
while True:
stuff = self._stuff_queue.get()
if stuff is not None:
self.something(stuff)
else:
break
def feed(self, stuff):
self._stuff_queue.put(stuff)
def something(self):
raise NotImplementedError("Implement this something !")
class Child(Parent):
def __init__(self):
# --- Swapping those two lines avoids getting the AttributeError --- #
super(Child, self).__init__() # Same thing using Parent.__init__(self)
self.counter = 0
def something(self, stuff):
self.counter += 1
print "Got stuff"
c = Child()
c.feed("Hi SO!")
c.feed(None) # Just to stop
以下是我得到的信息:
File "/home/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "test_process.py", line 14, in _do_something
self.something(stuff)
File "test_process.py", line 30, in something
self.counter += 1
AttributeError: 'Child' object has no attribute 'counter'
在子进程中调用self.counter=0之前,是否在父进程中调用了某个对象。您启动了一个进程来调用子进程。self.counter之前的某个对象已设置。谢谢,那么,为什么在启动线程而不是进程时不会产生错误?我在问题中添加了这一细节,因为当使用流程时,该流程中使用的实例将具有流程创建时的状态,而此时self.counter尚未设置。在这之后设置它不会有任何效果,因为这是在父进程的不同位置完成的。如果使用线程,那么对c.feed的调用总是在c完全初始化之后发生。如果在设置self.counter之前给它输入一些内容,那么就有一个争用条件,它可能工作,也可能不工作,这取决于线程调度。