事件类型标志的选择
在selectors模块中的开头直接定义了事件类型的标志数字,选用的是(1 << 0)就是1代替EVENT_READ读操作;使用(1 << 1)就是2代替EVENT_READ写操作,这样做的好处是能够交叉,使用一个数字代表两种模式,就像re模块中进行正则匹配的时候不同模式的组合一样。
缺省实现方式的选择
在selectors模块的最后有一段在我们使用 selectors.DefaultSelector() 的时候,会动态的根据我们当前操作系统来选择不同的implementation,即不同的实现,这种方式在python的标准库中有很多,比如os.path模块、pathlib.Path类等等,这些由于操作系统的不同所要进行不同的选择方式抽象出来就很值得我们学习了。
为何注册之后的文件对象会被封装成元组?
我们把一个socket对象selectors.DefaultSelector().register(socket, EVENT_READ, data=socket.accept)注册之后生成的是元组,这里模块内的说明没有介绍,这可能是跟python的设计有关,比如一个Selector可能监管很多个文件对象的IO,在事件驱动模型中由于文件对象会特别多,选择元组进行封装可以更节省内存。