问题

使用Python自带的socketserver类型来制作一个socks5代理,需要构建一个SocksProxy类,继承StreamRequestHandler类并实现handle方法。

在这个过程中,我想给SocksProxy类加个LogMixin模块,使用Mixin的多继承。LogMixin中,有self.logger,这个是一个日志对象,用来输出格式统一的日志。
此时问题来了,程序运行后,提示SocksProxy.logger不存在,开始排查。

基础知识

  • 多继承中的super函数,可以传入所有的父类的参数
  • 某些库在对象初始化之后就会立刻开始下一步,Mixin模块的初始化必须要在父类之前

解决方法

修改LogMixin的初始化顺序

1
2
3
4
5
6
7
8
class LogMixin()
def __init__(self, *keys, **kwargs):

_name = self.__class__.__name__
self.logger = logging.getLogger(name=_name)
self.logger.debug('创建日志功能 > {}'.format(_name))

super().__init__(*keys, **kwargs)

一般来说,Mixin类都会排在另一个父类的前面,所以最后一行把所有的super传入的参数全部往父类传递。

这里一定要在最后调用super(),因为有些类会在初始化Mixin之前的父类后直接开始运行;例如同时继承LogMixin和StreamRequestHandler的类,传递给ThreadingTCPServer类构造时,会导致Mixin无法正常初始化,父类构造完毕就直接开始运行了。根据源码看是StreamRequestHandler的父类初始化的时候就包含了开始运行的命令了,如下图
父类的初始化时直接开始运行

把Mixin的初始化写在父类的前面,这样就没有报错了😀