【问题标题】:How would I create and then import a package containing an unspecified set of modules?我将如何创建并导入包含一组未指定模块的包?
【发布时间】:2015-10-10 00:59:35
【问题描述】:

使用 Python 3.3 或更高版本,我将如何创建并导入包含一组未指定模块的包?我希望导入包中的所有模块,而不必按名称导入每个模块。这将允许将新模块添加到包中,并且下次导入包时可以自动加载新模块,而无需对包进行任何其他更改。

从包的外部,我希望导入和使用包看起来像这样:

import package
package.module.function()

从包的内部,我想导入和使用兄弟模块看起来像这样:

from . import sibling
sibling.function()

或者这个:

import package.sibling
package.sibling.function()

【问题讨论】:

    标签: python python-3.x python-3.3 python-importlib


    【解决方案1】:

    在 Python 3.3 或更高版本中,使用 pkgutil 搜索包目录并使用 importlib 加载每个模块。

    在包的__init__.py:

    # Import standard modules.
    import importlib
    import os
    import pkgutil
    
    # For each module in the current directory...
    for void, module_name, void in pkgutil.iter_modules([os.path.dirname(__file__)]):
    
        # Import the module.
        importlib.import_module(__name__+'.'+module_name)
    

    上面可以移动到一个库中,之后包的__init__.py变得简单:

    # Import local modules.
    import loader
    
    # Load all modules in the current directory.
    loader.load_all_modules(__file__,__name__)
    

    请注意,importlib 机制是在 Python 3.1 中引入的,并在 Python 3.3 中进行了重大更新,上述方法尚未在 Python 3.1.x 或 3.2.x 中进行测试。

    https://docs.python.org/3.3/library/importlib.html#importlib.import_module https://docs.python.org/3.3/library/pkgutil.html#pkgutil.iter_modules

    其他失败的方法

    尝试 1

    从包外,使用绝对导入:

    import package.module
    

    需要知道模块名称。

    尝试 2

    从包的__init__.py,使用绝对导入:

    import module
    

    需要知道模块名称。

    尝试 3

    来自包的__init__.py,设置__all__

    __all__ = ['module']
    

    需要使用:

    from package import *
    

    这会污染命名空间并且在任何情况下都可能是危险的,但在这种情况下尤其危险,因为模块的名称是未知的。

    尝试 4

    从包的__init__.py 中,使用pkgutil 识别和导入包中的所有模块似乎进行了导入,但仅模拟了本机导入机制并且不更新sys.modules 字典。当包中的模块尝试导入同级模块时,这会导致问题,例如:

    未在sys.modules 中列出会导致相对导入失败并显示以下消息:

    父模块''未加载,无法执行相对导入。

    http://hg.python.org/cpython/file/f7992397e98d/Lib/importlib/_bootstrap.py#l1518

    另外,绝对导入重新加载正在导入的模块。

    https://docs.python.org/3.3/library/imp.html#imp.load_module http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html#the-double-import-trap

    尝试 5

    从包的__init__.py 来看,使用importlib 似乎没有简单的方法来识别可导入的模块和子包,除非可能通过导入所有内容并捕获错误,并且这些误报错误消息使得更难识别当模块导入失败时发现合法问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多