4

我正在尝试动态加载我创建的模块。

现在这可以正常工作:

import structures.index

但是如果我通过动态导入来尝试同样的事情,它就会失败。

struct = __import__("structures.index")

提供的错误是:

Error ('No module named structures.index',)

任何想法为什么?


编辑:使用完整范围时(它有点工作?):

struct = __import__("neoform.structures.index")

这不会引发任何错误,但是,它没有加载索引模块,而是加载了“neoform”模块。

“结构”的结果是:

<module 'neoform' from '/neoform/__init__.py'>

另外,作为一个附带问题,我怎样才能在动态加载的模块中实例化一个类?(假设所有模块都包含一个公共类名)。

编辑:解决方案:(感谢 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))
4

7 回答 7

11

我不确定“它失败”是什么意思,所以我只提一下它__import__('structures.index')实际上应该可以工作,但它不会在当前范围内分配模块名称。为此(然后在动态导入的模块中使用一个类),您必须使用:

structures = __import__('structures.index')
structures.index.SomeClass(...)

完整的详细信息__import__在此处获得。

编辑:(基于问题编辑)

要导入neoform.structures.index并返回index模块,您将执行以下操作:

structures = __import__('neoform.structures.index', 
                        fromlist=['does not in fact matter what goes here!'])

因此,如果您有一个包名称列表,您可以使用以下代码packages导入它们的index模块并为每个模块实例化一些类:MyClass

modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a']) 
            for pkg in packages ]
objects = [ m.MyClass() for m in modules ]
于 2009-04-20T18:50:01.530 回答
4

要导入子模块,您需要在 Fo 示例的fromlistarg 中指定它们__import__()
,相当于:

import structures.index

是:

structures = __import__('structures', fromlist=['index'])

在地图中做到这一点有点棘手......

import mod1.index
import mod2.index
import mod3.index

对于这些导入,您需要定义一个新函数来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

现在,您可以这样做来获取对所有索引模块的引用:

index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])

此外,如果您想获取未命名为“索引”的子模块,那么您可以这样做:

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])
于 2009-04-20T18:52:45.377 回答
3

使用此辅助方法使用完整范围(“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
于 2009-04-20T21:23:16.793 回答
1

Java 程序员在这里,但我认为你需要imp 模块

于 2009-04-20T18:41:13.563 回答
1
>>> 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...

瞧!

于 2010-03-22T13:21:44.750 回答
0

你到底为什么要换

import structures.index

map(__import__, ["structures.index"])

第一个(a)有效,(b)动态的,(c)是直接支持的。有什么可能的用例可以用更复杂的东西替换易于更改的纯文本源?

简而言之:不要这样做。它没有任何价值。


编辑

“我正在从数据库中获取导入”是一项崇高的努力,但仍然不明智。哪些代码块取决于这些导入?整个代码块——导入和所有——就是你想要执行的。整个代码块——导入、语句和所有东西——应该是一个普通的旧 python 模块文件。

从文件系统中导入该代码块。使用数据库来识别哪个文件,文件的作者——任何你想使用数据库的东西。但只需以最简单的方式导入并执行模块。

于 2009-04-20T19:23:19.127 回答
0

真的很晚才在这里发帖。但我在谷歌上搜索这个问题。我做了一些试验和错误。不确定此代码段是否有帮助,但在这里。将其用于 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)
于 2013-03-15T02:00:00.733 回答