peh*_*hrs 23 python import plugins dynamic-class-loaders
我正在开发一个插件系统,插件模块加载如下:
def load_plugins():
plugins=glob.glob("plugins/*.py")
instances=[]
for p in plugins:
try:
name=p.split("/")[-1]
name=name.split(".py")[0]
log.debug("Possible plugin: %s", name)
f, file, desc=imp.find_module(name, ["plugins"])
plugin=imp.load_module('plugins.'+name, f, file, desc)
getattr(plugin, "__init__")(log)
instances=instances+plugin.get_instances()
except Exception as e:
log.info("Failed to load plugin: "+str(p))
log.info("Error: %s " % (e))
log.info(traceback.format_exc(e))
return instances
Run Code Online (Sandbox Code Playgroud)
代码有效,但是对于插件代码中的每个import语句,我都会收到如下警告:
plugins/plugin.py:2: RuntimeWarning: Parent module 'plugins' not found while handling absolute import
import os
Run Code Online (Sandbox Code Playgroud)
没有报告主程序代码的错误,插件工作.
有人可以解释警告意味着什么,我做错了什么.我是否需要单独创建一个空的插件模块并导入它以保持python的快乐?
Mik*_*ham 16
如果plugins目录没有__init__.py
,那么它不是一个包,所以当你创建时plugins.whatever
,Python警告你这样的东西不应该存在.(import plugins.whatever
无论你的路径是什么,它都无法通过" " 创建.)
也,
/
,这是不可移植的.使用os.path.split
..split(".py")
没有扩展名来获取名称,这是错误的.使用os.path.splitext
.getattr
字符串文字.getattr(plugin, "__init__")
是拼写的plugin.__init__
.__init__
函数.这似乎不对.也许您想要一个"set_logger"函数或更好的函数来实例化一个带记录器的类.L = L + some_other_list
用于扩展列表,使用extend
具有更好性能且更惯用的方法.except Exception
.如果你不能计划做一些理智的事情来回应异常,那么你的程序就不能理智.u0b*_*6ae 14
如果目录plugins
是真正的包(包含__init__.py
正常),您可以轻松地使用pkgutils枚举其插件文件并加载它们.
import pkgutil
# import our package
import plugins
list(pkgutil.iter_modules(plugins.__path__))
Run Code Online (Sandbox Code Playgroud)
但是,无论如何它都可以在没有插件包的情况下工作,试试这个:
import pkgutil
list(pkgutil.iter_modules(["plugins"]))
Run Code Online (Sandbox Code Playgroud)
还可以创建仅在运行时存在的包:
import types
import sys
plugins = types.ModuleType("plugins")
plugins.__path__ = ["plugins"]
sys.modules["plugins"] = plugins
import plugins.testplugin
Run Code Online (Sandbox Code Playgroud)
然而,那个黑客主要是为了好玩!
这里的问题是模块名称中的点('。'):
imp.load_module('plugins.'+name, f, file, desc)
不要包含“。” 在“插件”之后,否则Python会认为这是模块路径。
归档时间: |
|
查看次数: |
19123 次 |
最近记录: |