__import__ 和 import as 之间的 Python 区别

标签 python dynamic import

我正在尝试在 Python 中动态导入配置文件。

我的代码在我使用时工作正常:

import conf.config as config

但是当我使用时不能正常工作:

config = __import__("conf.config")

下面是示例程序和运行它们时得到的结果:

#regularimport.py
import conf.config as config

def read_values(cfg):
    for varname in cfg.__dict__.keys():
        if varname.startswith('__'):
            continue
        value = getattr(cfg, varname)
        yield (varname, value)

for name,value in read_values(config):
    print "Current config: %s = %s" % (name, value)

结果:

$python regularimport.py

Current config: SETTING_TWO = another setting
Current config: SETTING_ONE = some setting

动态导入:

#dynamicimport.py
conf_str = "conf.config"
config = __import__(conf_str)

def read_values(cfg):
    for varname in cfg.__dict__.keys():
        if varname.startswith('__'):
            continue
        value = getattr(cfg, varname)
        yield (varname, value)

for name,value in read_values(config):
    print "Current config: %s = %s" % (name, value)

结果:

$ python dynamicimport.py
Current config: config = <module 'conf.config' from '/home/ubuntu/importex/conf/config.pyc'>

我的问题是为什么不同?更重要的是,如何使动态导入示例像常规导入一样工作?

最佳答案

作为the documentation解释:

When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name.

所以,当你这样做时:

config = __import__("conf.config")

这不同于:

import conf.config as config

而是更像是:

import conf.config
config = conf

为什么?

因为 conf,而不是 conf.config,是被 import 语句绑定(bind)的东西。 (当然,在 import foo as bar 中,显然 bar 被绑定(bind)了……但是 __import__ 并不等同于 import foo as bar,但是 import foo。)文档进一步解释。但结果是您可能一开始就不应该使用 __import__


在函数文档的最顶部,它说:

Note: This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().

在底部,在解释了 __import__ 如何与包一起工作以及为什么这样工作之后,它说:

If you simply want to import a module (potentially within a package) by name, use importlib.import_module().

因此,正如您可能猜到的那样,简单的解决方案是使用 importlib.import_module .


如果您必须使用 Python 2.6,其中 importlib 不存在……好吧, 没有简单的解决方案。你可以用 imp 自己构建类似 import_module 的东西.或者使用 __import__ 然后挖掘 sys.modules。或者 __import__ 每个片段,然后 getattr 以您的方式处理结果。或者以其他各种骇人听闻的方式。是的,这很糟糕——这就是 3.0 和 2.7 修复它的原因。

2.6 文档给出了第二个 hack 的示例。根据您的情况进行调整:

__import__("conf.config")
config = sys.modules["conf.config"]

关于__import__ 和 import as 之间的 Python 区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21213355/

相关文章:

python - 如何将绘图保存为 pdf 文件,但它必须看起来像 plt.show() 的结果?

python - 根据另一个数据框的值在数据框中添加行

jquery - 使用 Jquery 设置内联 URL

python - 管理多个开发人员的 sys.path

r - 如何将二进制转换为数据?

python - 如何解决循环导入错误?

python - 将参数传递给torndb.query()

Python - 检查元组列表中的项目组合

javascript - Ext JS 选项卡面板不适合窗口大小

C++ vector : declaring multiple variables with names xxx1, xxx2....xxxN(N 从文件加载)