我目前正在编写一个程序,其中将Python文件复制到具有主模块的docker-container中,然后应在Threads中执行。
假设我具有以下结构:
.
├── app.py
├── rule1
| └── foo.py
├── rule2
| └── bar.py
:
: ...
:
└── ruleX
└── foobar.py
这个想法是,子目录中的每个.py
都实现一个接口,然后main.py
在其自己的线程中调用。另一方面,main.py
然后与主机上运行的程序进行通信。
线程唯一要做的就是创建已加载类的实例并调用.analyze()
函数。
到目前为止,我发现以下代码:
import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()
但是对于我来说,我不确定要为module.name
输入什么。以及如何调用该函数?
答案 0 :(得分:0)
查找此信息的地方是the documentation。您显然在某处找到的代码基本上只是one of the examples in the docs,所有解释和上下文都已删除。
您还需要对Python模块和软件包的工作原理有所了解,否则,您可以在同一文档章节中找到您不了解的所有内容。
但是对于我来说,我不确定要为
module.name
输入什么。
module.name
只是模块的名称。这是将在回溯中显示的名称,它可能会影响其他调试和反射代码(例如,如果您在任何地方使用inspect
),并且可能会从模块内部导入相对名称。 (我猜想,除了调试输出之外,这些都不会影响到您,在这种情况下,即使您弄错了也没有太大关系。)
无论如何,如果您不确定,并且希望看到一些示例而不是浏览干燥而混乱的文档,请打开交互式解释器,然后尝试以下操作:
import <whatever>
print(<whatever>.__name__, <whatever>.__file__)
…针对<whatever>
的不同值(从stdlib,从PyPI安装的软件包以及从您自己的项目)获得一个想法。您会看到__name__
的名称是由封面下的机器传递给spec_from_file_location
的。
但是简短的版本是:
rule1
像“命名空间包”一样使用,请使用rule1.foo
。rule1
充当sys.path上的另一个路径,请使用foo
。 该函数如何调用?
调用类的方式完全相同:
foo.analyze()
最后一件事:您要构建的是一个非常标准的插件系统,并使用最简单的插件API(“必须公开不带参数的函数analyze
”)。您可能需要四处寻找具有插件系统的其他应用程序,以阅读其代码以获取想法。 (但是请注意,其中许多控件都与Python 2.7或3.3向后兼容,这意味着导入的实际步骤将大不相同,并且您不想使用它们使用的旧代码。)