Python模块层次结构命名约定

9 投票
2 回答
12467 浏览
提问于 2025-04-17 18:05

我想要一个像下面这样的模块/包结构:

/__init__.py
/mymodule.py
/mymodule/
/mymodule/__init__.py
/mymodule/submodule.py

然后我想像这样使用这些模块:

import mymodule
import mymodule.submodule

但是看起来文件mymodule.pymymodule这个文件夹有冲突。

这里正确的命名规则是什么呢?

2 个回答

7

你正在处理一个。你应该有这样的包结构:

/some-parent-directory # This needs to be on sys.path
    /mymodule  # This is not really a module - it's a package
        __init__.py  # import mymodule
        # init is loaded when you `import mymodule` or anything below it
        some.py  # import mymodule.some
        implementation.py  # import mymodule.implementation
        files.py  # import mymodule.files
        /submodule
            __init__.py  # import mymodule.submodule
            # init is loaded when you `import mymodule.submodule` or anything below it
            submodule_impl.py  # import mymodule.submodule.submodule_impl
            goes.py  # import mymodule.submodule.goes
            here.py  # import mymodule.submodule.here

只要目录在sys.path中,你就可以顺利地使用import mymodule或者from mymodule.submodule import something来导入模块。

如果你想让某个东西可以从包的根目录直接使用(比如说from mymodule import SomeItem或者从子包from mymodule.submodule import AnotherItem),那么你可以把它导入到相应的__init__.py文件中。

举个例子,假设你想让在submodule_impl.py模块中定义的类CustomClass可以直接从submodule导入。你的submodule/__init__.py文件需要包含以下内容:

from .submodule_impl import CustomClass

这样你就可以直接从submodule导入CustomClass(也就是说from mymodule.submodule import CustomClass

14

如果你想制作一个包,你需要了解Python是如何把文件名转换成模块名的。

比如说,文件 mymodule.py 会被当作 mymodule 来使用,前提是解释器能在Python的搜索路径中找到这个文件。如果你使用的是不区分大小写的文件系统,那么这个模块可能还可以用不同的大小写来导入(不过最好还是避免这种依赖系统的行为)。

一个包就是一个文件夹,里面有一个 __init__.py 文件。最近有一些变化允许没有这个文件的包,但在这里我就不讨论这种不常见的情况了。包在Python中变成了一个模块,它的代码来自 __init__.py 文件。所以,文件 mypackage/__init__.py 可以被导入为 mypackage

在Python的搜索路径中,单独的 __init__.py 文件是没有特别意义的(当然,你可以把它当作一个 __init__ 模块来导入,但这可能不是个好主意)。

所以,对于你的情况,下面是合适的文件系统布局:

toplevel/
    mymodule/
        __init__.py     # put code here for mymodule
        submodule.py    # put code here for mymodule.submodule

只有 toplevel 文件夹应该在Python的搜索路径中。

撰写回答