我正在尝试将对象创建为新进程。如果我给该类提供初始化程序,则程序显示错误。
代码
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__()
插入初始化程序时,程序运行正常。
最终构造函数:
def __init__(self):
super(My_class, self).__init__()
self.name = "Hello "+self.name
self.num = 20
我在不同的上下文中找到了这一行并在这里尝试过,代码运行正常。
有人可以解释上述初始化中super(My_class, self).__init__()
行的工作是什么吗?
答案 0 :(得分:10)
当您在此处添加自己的__init__()
时,您覆盖超类中的__init__()
。但是,超类经常(在这种情况下)在__init__()
中有一些它需要的东西。因此,您必须重新创建该功能(例如,如您的错误中所述初始化_popen
,或者使用{{1)在新的构造函数中调用超类构造函数 ()或Python 3中的super(My_class, self).__init__()
。
答案 1 :(得分:3)
嗯,你班上没有_popen。
如果_popen是在类级别声明的,或者是mp.Process中的函数,那么您的代码将起作用,因为它会将它从Process名称空间中删除。
class Process(object):
_popen = None
def __init__(...):
#stuff, but not involving _popen
然而,断言看起来像一个警卫,我猜这段代码看起来有点像:
class Process(object):
def __init__(...):
#let's make sure that we don't open twice
self._popen = None
现在,在这种情况下,_popen仅在实例上设置,而不在Process类上设置。但是为了设置它,你需要执行那个mp.Process .__ init__代码。
如果你打电话给你的代码,那么你的代码就可以很好地工作了。这是你原来没做过的。
您可以使用
来调用它,而不是使用Superclass My_Class(mp.Process):
def __init__(self):
#
mp.Process.__init__(self)
....do your stuff....
这是我以前做的,它工作正常。但是,如果将继承更改为My_Class(mp.AnotherProcessType),则会中断。在这种情况下,任何对mp.Process.somefunc()的调用,而不仅仅是__init__都需要手动调整。
super(My_Class,self).init()在这种情况下最终会做同样的事情,但是为了调用mp.Process .__ init __而做家务是一种更健壮的方法。
有时你可以不在Python类的祖先上调用 init 。但这一切都取决于是否存在需要运行的初始化代码。在这种情况下,它看起来就像。
另外如果你的班级没有__init__那么你也不用担心,mp.Process .__ init__会被自动调用。但是你自己的__init__的存在基本上说是"我会做自己的初始化,非常感谢你"。如果需要,可以根据代码明确地将一些工作委托给祖先类。
P.S。不用担心,我发现super(xxx,self).somefunc()有点不太晦涩。但它确实有效。