Python模块层次结构命名约定
我想要一个像下面这样的模块/包结构:
/__init__.py
/mymodule.py
/mymodule/
/mymodule/__init__.py
/mymodule/submodule.py
然后我想像这样使用这些模块:
import mymodule
import mymodule.submodule
但是看起来文件mymodule.py和mymodule这个文件夹有冲突。
这里正确的命名规则是什么呢?
2 个回答
你正在处理一个包。你应该有这样的包结构:
/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
)
如果你想制作一个包,你需要了解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的搜索路径中。