Процесс подклассов Python с конструктором

Я пытаюсь создать объект как новый процесс. Если я даю конструктор классу, программа показывает ошибку.

код

import multiprocessing as mp 
import time

class My_class(mp.Process):
    def __init__(self):
            self.name = "Hello "+self.name
            self.num = 20

    def run(self):
        print self.name, "created and waiting for", str(self.num), "seconds"
        time.sleep(self.num)
        print self.name, "exiting"

if __name__ == '__main__':
    print 'main started'
    p1=My_class()
    p2=My_class()
    p1.start()
    p2.start()  
    print 'main exited'

File "/usr/lib64/python2.7/multiprocessing/process.py", line 120, in start
    assert self._popen is None, 'cannot start a process twice'
AttributeError: 'My_class' object has no attribute '_popen'

но когда вставить строку super(My_class, self).__init__() до constructor программа работает нормально.

окончательный конструктор:

def __init__(self):
    super(My_class, self).__init__()
    self.name = "Hello "+self.name
    self.num = 20

Я нашел эту строку в другом контексте и попробовал здесь, и код работает нормально.

Can кто-нибудь, пожалуйста, объясните, что такое работа линии super(My_class, self).__init__() В приведенном выше конструкторе?

2 ответов


когда вы добавляете свой собственный __init__() здесь переопределение на __init__() в суперклассе. Однако суперкласс часто (как в этом случае) имеет некоторые вещи, которые ему нужны в его __init__(). Поэтому вам либо нужно повторно создать эту функциональность (например, инициализация _popen как описано в вашей ошибке, среди прочего), или вызовите конструктор суперкласса внутри ваш новый конструктор с помощью super(My_class, self).__init__() (или super().__init__() в Python 3).


Ну, у вас нет _popen в вашем классе.

Если _popen был объявлен на уровне класса или был функцией в mp.Процесс, то ваш код б работа, потому что она захватит его из пространства имен процессов.

class Process(object):

    _popen = None

    def __init__(...):
       #stuff, but not involving _popen

assert выглядит как охранник, однако, и я предполагаю, что код выглядит примерно так:

class Process(object):


    def __init__(...):
       #let's make sure that we don't open twice
       self._popen = None

Теперь в этом случае _popen устанавливается только на экземпляре, а не в классе Process. Но для того, чтобы его установить, вам нужно выполнить Мп.Процесс._код _инит__.

ваш код будет работать отлично, если вы вызовете "процесс".__ init__', чего вы изначально не делали.

вместо использования Super вы можете вызвать его вместо

class My_Class(mp.Process):

   def __init__(self):
       #
       mp.Process.__init__(self)
       ....do your stuff....

это то, что я использовал, и он работает нормально. Но он ломается, если вы измените наследование, чтобы сказать My_Class (mp.AnotherProcessType). В таком случае, любые звонки в МП.Процесс.somefunc (), а не только _ _ init__ необходимо будет настроить вручную.

super (My_Class, self).init () в конечном итоге делает то же самое в этом случае, но это более надежный способ сделать домашнюю работу, чтобы вызвать mp.Процесс.__инициализация.__

иногда вы можете отказаться от вызова init на предке класса Python. Но все зависит от того, есть ли код инициализации, который должен бежать. А в данном случае, похоже, что есть.

также, если у вас не было __init__ в вашем классе тогда вам тоже не придется беспокоиться, Мп.Процесс.__init__ был бы вызван автоматически. Но существование вашего собственного _ _ init _ _ в основном говорит:"Я сделаю свою собственную инициализацию, большое спасибо". При необходимости ваш код должен явно делегировать некоторую работу классу ancestor.

p.s. не волнуйтесь, я нахожу супер (xxx, self).somefunc() немного ООН-pythonically непонятных, а также. Но это работает.