Python继承、超级调用顺序和AttributeError

Python继承、超级调用顺序和AttributeError,python,inheritance,attributeerror,python-multiprocessing,Python,Inheritance,Attributeerror,Python Multiprocessing,我不知道继承的类属性是如何初始化的。我在我认为定义良好的子属性上得到了AttributeError 我注意到在定义之后交换超级调用到父级的顺序不会产生错误,但我不理解为什么 我无法在不使用进程的情况下重现该错误,我也可以发布测试代码,但我认为这已经足够长了,似乎调用super的顺序并不重要 编辑:可能是因为在定义计数器之前运行一个进程导致了异常,但如果我使用线程而不是进程,则不会出现问题 我可能遗漏了一些关于初始值设定项是如何工作的,或者做错了什么 为什么会出现属性错误? 为什么交换两行可以解决

我不知道继承的类属性是如何初始化的。我在我认为定义良好的子属性上得到了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之前给它输入一些内容,那么就有一个争用条件,它可能工作,也可能不工作,这取决于线程调度。