使用初始化的Python子类化过程

时间:2015-02-25 04:54:04

标签: python class initialization

我正在尝试将对象创建为新进程。如果我给该类提供初始化程序,则程序显示错误。

代码

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__()行的工作是什么吗?

2 个答案:

答案 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__代码。

如果你打电话给你的代码,那么你的代码就可以很好地工作了。这是你原来没做过的。

您可以使用

来调用它,而不是使用Super
class 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()有点不太晦涩。但它确实有效。