Процесс подклассов 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 непонятных, а также. Но это работает.