与模块相同文件中的Python子模块

5

如果我现在有一个正在导入的文件:

from foo import f0
from foo.bar import f1

我可以在文件foo.py中创建一个函数f0来满足第一个import的需求。

有没有办法在同一个文件foo.py中满足第二个import的需求?

3个回答

9

我也想做同样的事情,但找到的问题都没有实际答案。所以,这是我想出来的解决方案:

import sys

def add_submodule(submod):
    name = submod.__name__
    sys.modules[__name__ + "." + name] = submod(name)


from types import ModuleType

class submod1(ModuleType):
    class foo:
        pass

class submod2(ModuleType):
    class bar:
        pass


add_submodule(submod1)
add_submodule(submod2)

实质上,您可以通过子类化types.ModuleType来定义一个模块。然后,将其手动添加到sys.modules中,位于当前模块的命名空间下,如__name__所示。
这是一种最简解决方案。如果需要将add_submodule()移动到单独的独立模块以供重用,则需要进行扩展: 不能简单地使用__name__,因为这将是add_submodule()所在命名空间。应该使用以下内容进行操作:
在单独的模块中:
def add_submodule(submod, parentname):
    name = submod.__name__
    sys.modules[parentname + "." + name] = submod(name)

在实际的模块中:

add_submodule(submod1, __name__)
add_submodule(submod2, __name__)

我担心没有更好的方法把父级的名称传递给函数中。


现在可以这样使用这两种情况:

In [1]: import submodtest.submod1 as sm1

In [2]: import submodtest.submod2 as sm2

In [3]: sm1. [TAB]

sm1.foo sm1.mro

In [3]: sm2. [TAB]

sm2.bar sm2.mro


编辑:将以上完整示例推送到我的Github


-4
创建一个名为foo的目录
  • 在这个目录中,有一个名为__init__.py的文件
  • 这实际上创建了一个名为foo的模块
  • 在这个文件中,存储你想要与foo捆绑在一起的函数

在foo下创建一个名为bar的子目录

  • 在这个目录中,有一个名为__init__.py的文件
  • 这实际上创建了一个名为foo.bar的子模块
  • 在这个文件中,存储你想要与foo.bar捆绑在一起的函数

3
这并没有回答问题。我的问题是希望找到一个只使用名为 foo.py 的文件的解决方案。更宽松版本的问题允许使用 foo.py 文件导入其他文件。 - Alex Rothberg
1
也许值得指出一下,我为什么想要这样做:我正在使用一个给定的库(实际上是编译好的 C++ 代码),它与我不总是能够访问的硬件进行通信。因此,我想模拟一些可替换的内容来处理代码。但是,我希望这是一个单独的文件,这样就不会在我的工作目录中产生太多污染。不过,我不知道这是否与 @Alex 想要的类似... - NichtJens

-5
不,你应该创建一个名为foo的目录作为一个包。
点击这里阅读有关导入系统的官方文档。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接