Python 模块的动态加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/769534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic Loading of Python Modules
提问by Ian
I'm trying to dynamically load modules I've created.
我正在尝试动态加载我创建的模块。
Right now this works properly:
现在这可以正常工作:
import structures.index
But if I try the same thing by importing it dynamically, it fails.
但是如果我通过动态导入来尝试同样的事情,它会失败。
struct = __import__("structures.index")
Error supplied is:
提供的错误是:
Error ('No module named structures.index',)
Any ideas why?
任何想法为什么?
Edit: When using full scope (it sort of works?):
编辑:使用全范围时(它有点工作?):
struct = __import__("neoform.structures.index")
This doesn't throw any errors, however, it isn't loading the index module, it's loading the "neoform" module instead.
这不会引发任何错误,但是,它不是加载索引模块,而是加载“neoform”模块。
The result of "struct" is:
“结构”的结果是:
<module 'neoform' from '/neoform/__init__.py'>
Also, as a side question, how can I then instantiate a class within a dynamically loaded module? (assuming all the modules contain a common class name).
另外,作为一个附带问题,我怎样才能在动态加载的模块中实例化一个类?(假设所有模块都包含一个公共类名)。
Edit: Solution: (thanks coonj & Rick) This ended up being what worked. Not sure why (yet), but the fromlist
had to be something "anything apparently, since it worked when I put the letter "a" as a value (strange, given that the file only had 1 class in it).
编辑:解决方案:(感谢 coonj 和 Rick)这最终奏效了。不知道为什么(还),但是fromlist
必须是“任何显然的东西,因为当我将字母“a”作为值时它起作用(奇怪,因为文件中只有 1 个类)。
def get_struct_module(self, name):
try:
return = __import__("neoform.structures." + name, fromlist='*')
except ImportError, e:
self.out.add("Could not load struct: neoform.structure." + name + "\n\n" + "Error " + str(e.args))
回答by Rick Copeland
I'm not sure what "it fails" means, so I'll just mention that __import__('structures.index')
should, in fact, work, but it doesn't assign the module name in the current scope. To do that (and then use a class in the dynamically imported module), you'll have to use:
我不确定“它失败”是什么意思,所以我只是提到它__import__('structures.index')
实际上应该可以工作,但它不会在当前范围内分配模块名称。为此(然后在动态导入的模块中使用一个类),您必须使用:
structures = __import__('structures.index')
structures.index.SomeClass(...)
The complete details on __import__
are available here.
的完整详细信息__import__
可在此处获得。
Edit: (based on question edit)
编辑:(基于问题编辑)
To import neoform.structures.index
, and return the index
module, you would do the following:
要导入neoform.structures.index
并返回index
模块,您将执行以下操作:
structures = __import__('neoform.structures.index',
fromlist=['does not in fact matter what goes here!'])
So if you have a list of package names packages
, you can import their index
modules and instantiate some MyClass
class for each using the following code:
因此,如果您有一个包名称列表packages
,您可以导入它们的index
模块并MyClass
使用以下代码为每个模块实例化一些类:
modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a'])
for pkg in packages ]
objects = [ m.MyClass() for m in modules ]
回答by Jason Coon
To import sub-modules, you need to specify them in the fromlist
arg of __import__()
Fo example, the equivalent of:
要导入子模块,需要在Fo 示例的fromlist
arg 中指定它们__import__()
,相当于:
import structures.index
is:
是:
structures = __import__('structures', fromlist=['index'])
To do this in a map is a little more tricky...
在地图中做到这一点有点棘手......
import mod1.index
import mod2.index
import mod3.index
For those imports, you would want to define a new function to get the index
sub-module from each module:
对于这些导入,您需要定义一个新函数来index
从每个模块中获取子模块:
def getIndexMods(mod_names):
mod_list = map(lambda x: __import__(x, fromlist='index'))
index_mods = [mod.index for mod in mod_list]
return index_mods
Now, you can do this to get references to all index modules:
现在,您可以这样做以获取对所有索引模块的引用:
index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])
Also, if you want to grab sub-modules that are not named 'index' then you could do this:
此外,如果您想获取未命名为“index”的子模块,则可以执行以下操作:
mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y),
['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])
回答by FogleBird
Use full scope ("neoform.structures.index") with this helper method.
使用此辅助方法的完整范围(“neoform.structures.index”)。
def import_module(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
module = import_module("neoform.structures.index")
# do stuff with module
回答by rorycl
>>> import imp
>>> fm = imp.find_module('index', ['./structures']) # for submodule
>>> mymod = imp.load_module('structures.index', *fm)
>>> mymod
<module 'structures.index' from './structures/index.pyc'>
>>> x = mymod.insideIndex()
Initialising index class...
Voila!
瞧!
回答by dfa
Java programmer here, but I think you need the imp module
Java程序员在这里,但我认为你需要imp模块
回答by S.Lott
Why on earth would you replace
你到底为什么要更换
import structures.index
with
和
map(__import__, ["structures.index"])
The first one (a) works, (b) isdynamic and (c) is directly supported. What possible use case is there for replacing easy-to-change, plain-text source with something more complex?
第一个 (a) 有效,(b)是动态的,(c) 是直接支持的。有什么可能的用例可以用更复杂的东西替换易于更改的纯文本源?
In short: don't do this. It doesn't have any value.
简而言之:不要这样做。它没有任何价值。
Edit
编辑
The "I'm getting the import from a database" is a noble effort, but still not sensible. What code block depends on those imports? That whole code block -- imports and all -- is what you want to execute. That whole code block -- imports, statements and everything -- should be a plain old python module file.
“我正在从数据库获取导入”是一项崇高的努力,但仍然不明智。哪些代码块取决于这些导入?整个代码块——导入和所有——就是你想要执行的。整个代码块——导入、语句和一切——应该是一个普通的旧 python 模块文件。
Import that block of code from the file system. Use the database to identify which file, the author of the file -- anything you want to use the database for. But simply import and execute the module the simplest possible way.
从文件系统导入该代码块。使用数据库来识别哪个文件,文件的作者——任何你想使用数据库的东西。但只需以最简单的方式导入和执行模块。
回答by jdsantiagojr
Really late post here. But I was searching for this question on google. I did some trial and error. Not sure if this snippet will help but here it is. Using it for Flask site.
在这里发帖真的晚了。但是我在谷歌上搜索这个问题。我做了一些试验和错误。不确定这个片段是否会有所帮助,但它在这里。将其用于 Flask 站点。
modules = ['frontend', 'admin']
for module in modules:
mod = __init__('controllers.%s' % module, fromlist=[module])
app.register_blueprint(mod.blueprint_mod)
# or
from importlib import import_module
modules = ['frontend', 'admin']
for module in modules:
mod = import_module('controllers.%s' % module)
app.regitster_blueprint(mod.blueprint_mod)