Python模块的动态加载

发布于 2024-07-17 05:10:11 字数 1032 浏览 7 评论 0原文

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

现在这工作正常:

import structures.index

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

struct = __import__("structures.index")

提供的错误是:

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

有什么想法吗?


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

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

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

“struct”的结果是:

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

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.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

过度放纵 2024-07-24 05:10:11

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

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

有关 __import__ 的完整详细信息可在此处

编辑:(基于问题编辑)

要导入 neoform.structurals.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 ]

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:

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

The complete details on __import__ are available here.

Edit: (based on question edit)

To import neoform.structures.index, and return the index module, you would do the following:

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:

modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a']) 
            for pkg in packages ]
objects = [ m.MyClass() for m in modules ]
旧话新听 2024-07-24 05:10:11

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

import structures.index

是:

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

To do this in a map 有点棘手......

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'])

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

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])

To import sub-modules, you need to specify them in the fromlist arg of __import__()
Fo example, the equivalent of:

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:

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:

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])
贵在坚持 2024-07-24 05:10:11

使用此辅助方法的完整范围(“neoform.structs.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

Use full scope ("neoform.structures.index") with this helper method.

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
无声静候 2024-07-24 05:10:11
>>> 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...

瞧!

>>> 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!

心房的律动 2024-07-24 05:10:11

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

Java programmer here, but I think you need the imp module

执笏见 2024-07-24 05:10:11

你到底为什么要替换

import structures.index

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

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

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


编辑

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

从文件系统导入该代码块。 使用数据库来识别哪个文件、文件的作者——任何您想要使用数据库的内容。 但只需以最简单的方式导入并执行模块即可。

Why on earth would you replace

import structures.index

with

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

The first one (a) works, (b) is dynamic and (c) is directly supported. What possible use case is there for replacing easy-to-change, plain-text source with something more complex?

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.

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.

千秋岁 2024-07-24 05:10:11

这里发帖真的晚了。 但我正在谷歌上搜索这个问题。 我做了一些尝试和错误。 不确定这个片段是否有帮助,但就在这里。 将其用于 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)

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.

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文