如何给__import__动态引入的文件添加库(在线等,解决 V 币感谢)

2018-08-28 15:51:38 +08:00
 akmonde

现在我这边有个问题,由于存在多个不规则插件,所以在入口文件处,通过__import__加载路径对多个插件进行引用。

不过由于某些原因,调用插件时,插件并没有能继承入口文件中已经引入的库(包括公共库和 diy 的第三方库)。

所以现在需要想法子,需要给插件动态引入库,不然各个插件会因为缺失库报错。这里实在不想人工给每个插件都 import 一遍一坨库,法子有点蠢而且不实用。

解决尝试:

本来想试试 setattr 啥的,不过好像只能赋值,不能引用库。
又尝试给多个子级目录添加了__init__.py ,再在里面 import 库,也没有生效。

请问大佬们有没有相应的解决方案?

2589 次点击
所在节点    Python
28 条回复
wwqgtxx
2018-08-29 10:59:44 +08:00
@skinny 说实话,我觉得你的实现方法并不能解决题主在 3#描述的问题,你的方案只是解决了批量导入模块的问题,却没办法在导入模块前动态给模块的开头加上 import
wwqgtxx
2018-08-29 11:04:30 +08:00
应该是 6#刚才打错了
skinny
2018-08-29 14:38:41 +08:00
@wwqgtxx 确实没办法。实际上我也没有找到 Python 模块注入 100%可行的办法,确切的说没有找到正常的在 import 前设置符号表的方法。如果他的插件模块在模块域就使用了未导入的模块名字,那目前我没有找到办法,如果是在类或函数时还好,批量导入时对那个模块设置下模块名字就好了。

伪代码:
def walk_modules(path):
.... ....
.... mod = import_module(path)
.... mod.sys = sys # or import_module('sys')
.... ....

如果不愿意重构,就写个脚本批量处理下那些插件代码呗。
wwqgtxx
2018-08-29 16:23:31 +08:00
@skinny 基本上除了我在#16 提供的使用 exec 的方法以外,想要动态重构一个模块还真的很难。你提供的方法只要模块能正常的被 import 就能把其他模块比如 sys 注入,但是如果在 import 的时候就直接报错 ImportError 之类的就无能为力了。而我提供的方法其实是完全自己手动模拟的 import 的过程,但是无法解决出现一个插件内部 import 另一个插件的情况(当然也可以在 read 之后把文件内部的 import 再 hook 一下,不过这样就非常的臃肿了)。
看楼主的描述,其实是那些个插件本身写的就有语法问题
至于楼主说的“插件居然不能继承入口文件里面引入的库文件”,其实这是个很合理的行为,每个.py 文件都有一个自己独立的作用域,换句话说,除非手动 import 否则各个模块之间应该互相不干扰,贝莱就没有所谓的入口文件的概念,自然也就不存在继承的问题
skinny
2018-08-29 17:19:51 +08:00
@wwqgtxx 你都读入模块源代码拼接了 import 语句了,还不如写个脚本一次性处理下那些脚本。说真的,按描述看,楼主那些插件代码一塌糊涂,得重写才能避免那些问题。
baojiweicn2
2018-08-29 17:42:01 +08:00
akmonde
2018-08-29 22:44:04 +08:00
@skinny
@wwqgtxx
讲真那些插件代码应该没问题,github 上搜罗的,不算是我的锅...
我想了想,可能是因为使用了 celery 的 subtask 调用的插件,才造成不能共享库的作用域,直接调用插件的话库本来可以共享作用域的。

@baojiweicn2 emmmm,查了下,好像这条是 celery 任务自动运行所有已注册的 app 吧。我那边呢,是需要动态导入一批未知名的模块,然后再将它们注册成 celery app 再运行,估计这法子可能不大合适。
akmonde
2018-08-31 12:10:26 +08:00
@wwqgtxx
@skinny
最后還是選了把需要包含的庫,寫進一個單獨的文件,然後再直接在所有插件的頭部插入 import....真香,居然還是用了老辦法...
最後還遇到個坑,workflow 的 chord 等等,win 下不支持的( celery v3.x ),排錯花了老半天。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/483983

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX