在运行时导入Python 3.6

时间:2018-06-22 20:01:33

标签: python python-3.x

我目前正在编写一个程序,其中将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输入什么。以及如何调用该函数?

1 个答案:

答案 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向后兼容,这意味着导入的实际步骤将大不相同,并且您不想使用它们使用的旧代码。)