Python:从python命名空间/包中导入所有内容

时间:2012-08-31 18:46:27

标签: python namespaces package

所有

我认为这很容易回答,但事实并非如此。只要我一直在寻找答案,我一直在想,我忽略了一些简单的事情。

我有一个具有以下包结构的python工作区:

    MyTestProject
        /src
           /TestProjectNamespace
              __init__.py
              Module_A.py
              Module_B.py

    SecondTestProject
        /src
           /SecondTestProjectNamespace
              __init__.py
              Module_1.py
              Module_2.py
              ...
              Module_10.py

请注意,MyTestProjectNamespace引用了SecondTestProjectNamespace。

在MyTestProjectNamespace中,我需要导入SecondTestProjectNamespace中的所有内容。我可以使用以下语句一次导入一个模块:

    from SecondTestProjectNamespace.Module_A import *
    from SecondTestProjectNamespace.Module_B import *

...但如果SecondTestProject中有50个模块,这是不切实际的。

Python是否支持导入命名空间/包中的所有内容?任何帮助,将不胜感激。

提前致谢。

4 个答案:

答案 0 :(得分:1)

没有。可以将SecondTestProject设置为自动导入其子模块中的所有内容,方法是将代码放在__init__.py中以执行您提到的from ... import *。也可以使用__import__函数和/或imp模块在​​某种程度上自动执行此操作。但是没有快速简便的方法来获取这样设置的包,并使其以这种方式工作。

无论如何,这可能不是一个好主意。如果你有50个模块,将所有模块中的所有模块导入到全局命名空间中会导致名称激增,并且很可能会在这些名称之间发生冲突。

答案 1 :(得分:1)

是的,您可以使用pkgutil进行滚动。

这是一个列出扭曲(测试除外)的所有包的示例,并导入它们:

# -*- Mode: Python -*-
# vi:si:et:sw=4:sts=4:ts=4

import pkgutil
import twisted

for importer, modname, ispkg in pkgutil.walk_packages(
    path=twisted.__path__,
    prefix=twisted.__name__+'.',
    onerror=lambda x: None):
        # skip tests
        if modname.find('test') > -1: 
            continue
        print(modname)
        # gloss over import errors
        try:
            __import__(modname)
        except:
            print 'Failed importing', modname
            pass

# show that we actually imported all these, by showing one subpackage is imported
print twisted.python

我必须同意其他海报,明星进口是一个坏主意。

答案 2 :(得分:1)

正如其他人所说的那样 - 这可能不是一个好主意。但是有一些方法可以保留你的命名空间,从而避免命名冲突 - 并且只需一次导入就可以将包中的所有模块/子包用于包用户。

假设我有一个名为“pack”的包,其中包含一个名为“a.py”的模块,用于定义一些“b”变量。我想做的就是:

>>> import pack
>>> pack.a.b
1

这样做的一种方法是在pack/__init__.py中输入一行说明 import a - 因此,在您的情况下,您需要这些线条,并让它们保持最新状态。

没那么糟。

但是,http://docs.python.org/tutorial/modules.html#importing-from-a-package处的文档说 - 如果您的__all__文件中有一个名为__ini__.py的字符串列表,则该列表中的所有模块/子包名称都会导入一个人做from pack import *

仅此一半就可以完成 - 但是请求您的软件包用户执行不推荐的“from x import *”表单。

但是 - 在定义__init__.py变量后,你可以在__all__内部执行“... import *” - 所以你所要做的就是保持__all__最新:

TestProjectNamespace/__init__.py是这样的:

__all__ = ["Module_A", "Module_B", ...]
from TestProjectNamespace import *

您的用户会有 TestProjectNamespace.Module_A(以及其他)在导入TestProjectNamespace时可用。

当然,你可以自动创建__all__ - 毕竟它只是一个变量 - 但我不会推荐它。

答案 3 :(得分:0)

  

Python是否支持导入命名空间/包中的所有内容?

没有。包不是超级模块 - 它是组合在一起的模块集合。


至少部分原因是确定文件夹中“一切”的含义并非易事:网络驱动器,软链接,硬链接等问题......