简体   繁体   English

在运行时导入Python 3.6

[英]Python 3.6 import at runtime

I'm currently writing a program where Python-Files are copied into a docker-container with a main module and should then be executed in Threads. 我目前正在编写一个程序,其中将Python文件复制到具有主模块的docker-container中,然后应在Threads中执行。

Suppose I have the following structure: 假设我具有以下结构:

.
├── app.py
├── rule1
|   └── foo.py
├── rule2
|   └── bar.py
:
:   ...
: 
└── ruleX
    └── foobar.py

The idea is, that each .py in a subdirectory implements an interface and is then called in it's own Thread by the main.py . 想法是,子目录中的每个.py都实现一个接口,然后由main.py在其自己的线程中main.py The main.py on the other hand then communicates with the program running on the host. 另一方面, main.py然后与主机上运行的程序进行通信。 The only thing the Thread would have to to, would be to create an instance of the loaded class and call the .analyze() -function. 线程唯一要做的就是创建已加载类的实例并调用.analyze() -function。

As far I found the following code: 到目前为止,我发现以下代码:

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()

But in my case I am not sure what to enter for module.name . 但就我而言,我不确定为module.name输入什么。 And how can the function be called? 以及如何调用该函数?

The place to look for this information is the documentation . 查找此信息的地方是文档 The code that you apparently found somewhere is basically just one of the examples in the docs with all the explanation and context stripped out. 您显然在某处找到的代码基本上只是文档中的示例之一 ,所有说明和上下文都已删除。

You do also need to understand a little bit about how Python modules and packages work, but otherwise, anything you don't understand here should be findable within the same doc chapter. 您还需要稍微了解一下Python模块和软件包的工作方式,但是否则,您在此处不了解的所有内容都应在同一文档章节中找到。


But in my case I am not sure what to enter for module.name . 但就我而言,我不确定为module.name输入什么。

module.name is just the name of the module. module.name只是模块的名称。 It's the name that will show up in tracebacks, and it may affect other debugging, and reflective code (eg, if you're using inspect anywhere), and possibly relative imports from within the module. 这是将在回溯中显示的名称,它可能会影响其他调试和反射代码(例如,如果您在任何地方使用inspect ),以及可能从模块内部导入的相对名称。 (I'm guessing that, other that debugging output, none of this is going to affect you, in which case it doesn't even matter that much if you get it wrong.) (我猜想,除了调试输出之外,所有这些都不会影响您,在这种情况下,即使您弄错了它也没有太大关系。)

Anyway, if you're not sure, and want to see some examples rather than dig through dry and confusing documentation, open the interactive interpreter and try this: 无论如何,如果不确定,并且希望看到一些示例而不是浏览干燥而混乱的文档,请打开交互式解释器,然后尝试以下操作:

import <whatever>
print(<whatever>.__name__, <whatever>.__file__)

… for different values of <whatever> (from the stdlib, and from packages you've installed off PyPI, and from your own project) to get an idea. …针对不同的<whatever>值(从stdlib,从PyPI安装的软件包以及从您自己的项目)获得一个想法。 The __name__ you see there is the name that got passed to spec_from_file_location by the machinery under the covers. 您看到的__name__是由spec_from_file_location下的机器传递给spec_from_file_location的名称。

But the short version is: 但简短的版本是:

  • If you want rule1 to act like a "namespace package", use rule1.foo . 如果希望rule1像“命名空间包”一样使用,请使用rule1.foo
  • If you want rule1 to act like just another path on sys.path, use foo . 如果要让rule1像sys.path上的另一个路径一样工作,请使用foo

And how can the function be called? 以及如何调用该函数?

The exact same way you were calling a class: 调用类的方式完全相同:

foo.analyze()

One last thing: what you're building is a pretty standard plugin system, with the simplest possible plugin API ("must expose a function analyze that takes no parameters"). 最后一件事:您正在构建的是一个非常标准的插件系统,具有最简单的插件API(“必须公开不带参数的函数analyze ”)。 You might want to look around for other applications with plugin systems to read their code for ideas. 您可能需要四处寻找具有插件系统的其他应用程序,以阅读其代码以获取想法。 (But be aware that many of them are made to be backward compatible with Python 2.7 or 3.3, which means that the actual steps for importing will be very different, and you don't want to use the old-style code they use.) (但是请注意,其中许多控件都与Python 2.7或3.3向后兼容,这意味着导入的实际步骤将大不相同,并且您不想使用它们使用的旧代码。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM