python系列2:谈下Python3中super()的用法

查了很多资料,感觉网上有些资料的理论说明很有用,理解更深,但也有一些应用误导,记录在此。

问题

首先,一个项目中需要定义一个类,这个类需要继承2个类,这2个类又各自继承了不少其他类。然后每个类的初始化需要带一些各自的参数,导致super的时候报错。python系列2:谈下Python3中super()的用法_第1张图片

问题分析

super().init()应该是从子类开始依次找父类的初始化__init__构造函数,但是socketserver.ThreadingTCPServer继承如下
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

然后TCPServer的__init__部分代码如下:
def init(self, server_address, RequestHandlerClass, bind_and_activate=True):
“”“Constructor. May be extended, do not override.”""
BaseServer.init(self, server_address, RequestHandlerClass)
self.socket = socket.socket(self.address_family,
self.socket_type)

ThreadingMixIn没有__init__

再然后BaseServer是 这样的:
def init(self, server_address, RequestHandlerClass):
“”“Constructor. May be extended, do not override.”""
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
所以会出现上述错误。

解决

如下图。这里要特别说明一下,个人理解
super(myQObject, self).init()就是直接从子类显式继承的父类中开始调用了__init__方法,而不是网上传的比较多的理解,super()从MRO表中返回传入的myQObject的下一个类,如
[main.SktTCPServer’>, , , , , , , , ]。
从print(super()),print(super(myQObject))可以看出来。
因此如果不想从子类开始super(因为有时候__init__需要传递同父类不一样的参数,同时又需要继承父类__init__特性),可以直接从父类入手开始super()
如:
super(myQObject, self).init()
super(socketserver.ThreadingTCPServer, self)
.init(self.server_address, RequestHandlerClass, self.bind_and_activate)
然后子类
SktTCPServer(socketserver.ThreadingTCPServer, myQObject):
就可以愉快的用自己的和父类的__init__啦。
问题解决!

python系列2:谈下Python3中super()的用法_第2张图片

你可能感兴趣的:(Python)