【问题标题】:Python dynamic import - how to import * from module name from variable?Python 动态导入 - 如何从变量中的模块名称导入 *?
【发布时间】:2017-06-12 06:36:26
【问题描述】:

正如here 所讨论的,我们可以使用字符串变量动态导入模块。

import importlib
importlib.import_module('os.path')

我的问题是如何从字符串变量import *?

这样的东西暂时不工作

importlib.import_module('os.path.*')

【问题讨论】:

  • 你为什么要这样做? *-imports 通常不受欢迎,它们会使命名空间变得混乱,并且您最终可能会导入您不想要的东西(例如,更新了模块,获取了覆盖早期导入的新函数)。您是否有动态执行此操作的具体用例?
  • 我知道使用import * 听起来很危险;虽然它适用于简单的用例。我的具体用例是我正在尝试使用proboscis 运行python test,这允许我选择要运行的测试套件 - 所选的测试套件由一组测试文件名定义。

标签: python python-import


【解决方案1】:

您可以使用以下技巧:

>>> import importlib
>>> globals().update(importlib.import_module('math').__dict__) 
>>> sin
<built-in function sin>

请注意,使模块中的所有名称在本地可用,因此它与* 略有不同,因为它不以__all__ 开头,例如它还将覆盖__name__、__package__、__loader__、__doc__。

更新:

正如@mata 在comments 中指出的那样,这是一个更精确、更安全的版本:

module = importlib.import_module('math')

globals().update(
    {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
    else 
    {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')
})

特别感谢 Nam G VU 帮助使答案更完整。

【讨论】:

  • 这也会导入__name__、__package__、__loader__、__doc__等你绝对不想导入的东西。
  • 不仅仅是一种罪
  • if not k.startswith('_') 可能会更好。进行* 导入时,真正的导入机制还会检查模块是否具有__all__ 属性,并且只导入那里给出的内容。
  • 感谢您的技巧!现在看起来好多了,我只是跳过了 __all__ 让它有点短 sn-p 但你的建议也足够好,可以隐藏以 _ 开头的函数
  • module = importlib.import_module('math'); globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')}) 行中的东西,只有formatted nicer
猜你喜欢
  • 2023-02-04
  • 2016-08-15
  • 2023-03-21
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多