Python模块动态加载
这个需求之前不是没见过,当你在编写服务时,请求的服务不确定,因此在你的后端程序中需要根据请求的具体服务加载对应的模块或者函数;
比如,我接盘的代码结构大致如下:
mod1和mod2底下分别有多个函数;请求过来的可能是某个具体的函数名,字符串格式的'function1' ,现在的需求就是根据这个'function1'加载出调用的函数。
动态加载实现的基本方法是使用内建函数_import__(name, fromlist=[]), 这个函数是import语句的实际调用;至于两个参数怎么传,我先说结论:
结论:_import_('A.B') ,fromlist为空时导入的是A,不为空时(随便填什么)导入的是B;
因此我想直接根据函数名导入mod1中的函数时需要这样:mod1 = _import_('Package.mod1.func1', fromlist=['func1']) == from Package.mod1 import func1
至于为什么,参考下回答Why does Python's __import__ require fromlist?stackoverflow.com
说实话,我也没太搞懂;
第二个需求,我想写一个聚合服务,把一个包下面所有模块的所有函数的返回结果聚合在一起,前提是假设你并不知道函数名称,只知道要获取里面所有函数的返回;
解决方式:
# 获取pkg目录下的模块名称(字符串)
mod_nameList = os.listdir('./')
# 可以用一些正则筛选
#根据名称加载真正的可调用的模块
module_list = [__import__('pkg'+mod_name, fromlist=[mod_name]) for mod_name in mod_name_list]
# 筛选函数
from inspect import getmembers, isfunction
func_list = [v for mod in module_list for k, v in getmembers(mod) if isfunction(v)]
上述方式主要使用了getmembers函数,可以对模块中的组成进行检查,筛选出函数。
Flask的并发问题
不知道什么时候吃了一个洗脑包说Flask是单线程会阻塞的程序,不能同时处理多个请求...;经过我的多并发实验和学习,得出结论:Flask本身具备多线程并发的能力,1.0之前只需在app.run(threaded=True)传入True即可;1.0之后默认为True;
因此,如果的你Flask服务只是在小组内部,有限个请求人数调用时,根本不需要什么gunicore或者niginx的解决方案,Flask自己的Thread方案就够了;
有意思的是,flask是怎么保证线程安全的,以及他如何区分全局的request对象。flask巧妙地使用了上下文和Thread.local机制,使其不用像django一样吧request参数传来传去。
Vscode插件推荐
在搬砖过程中,仍有同时坚持Xshell+Vim或者Xshell+Pycharm+git/ftp 的工作模式;Vscode的remote-ssh简直太好用了!
搭配vs-code的编译环境、git支持和语言支持等,几乎解决了所有开发需求。。。相见恨晚的插件;
不过这个插件如果装在Win上时需要先安装Openssh,Mac则不需要(本身带有ssh);
下篇搬砖日记啥时候呢?。。。