2

全部。

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

我有一个具有以下包结构的 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

4 回答 4

1

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

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

于 2012-08-31T18:56:21.560 回答
1

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

下面是一个示例,列出了 twisted 下的所有包(测试除外)并导入它们:

# -*- 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

我不得不同意其他海报的明星进口是个坏主意。

于 2012-08-31T19:01:12.223 回答
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__,则__init__.py所有模块/子包名称都在该列表是在一个时导入的from pack import *

仅此一项就可以完成一半 - 但需要您的包的用户执行不推荐的“从 x 导入 *”表单。

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

TestProjectNamespace/__init__.py这样:

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

您的用户将在导入 TestProjectNamespace 时获得 TestProjectNamespace.Module_A (和其他)。

而且,当然 - 你可以自动创建__all__- 毕竟它只是一个变量 - 但我不建议这样做。

于 2012-08-31T19:14:52.667 回答
0

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

不,包不是超级模块——它是组合在一起的模块的集合。


至少部分原因是确定文件夹中“所有内容”的含义并非易事:存在网络驱动器、软链接、硬链接等问题......

于 2012-08-31T18:54:03.600 回答