如何编写好的/correct __init__.py 文件
我的包的结构如下:
mobilescouter/
__init__.py #1
mapper/
__init__.py #2
lxml/
__init__.py #3
vehiclemapper.py
vehiclefeaturemapper.py
vehiclefeaturesetmapper.py
...
basemapper.py
vehicle/
__init__.py #4
vehicle.py
vehiclefeature.py
vehiclefeaturemapper.py
...
我不太确定 __init__.py
文件应该怎么写才算正确。
__init__.py #1
看起来是这样的:
__all__ = ['mapper', 'vehicle']
import mapper
import vehicle
那么,比如说 __init__.py #2
应该是什么样子的呢?我的内容是:
__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml
什么时候应该使用 __all__
呢?
3 个回答
你的 __init__.py
文件里应该有一个 文档字符串。
虽然所有的功能都是在模块和子包中实现的,但你的包的文档字符串是用来说明从哪里开始的地方。例如,可以看看这个 python 的 email
包。这个包的文档就像是一个介绍,讲述了它的目的、背景,以及包内各个组件是如何协同工作的。如果你使用 sphinx 或其他工具自动生成文档,包的文档字符串正是描述这种介绍的最佳位置。
关于其他内容,可以参考 firecrow 和 Alex Martelli 的精彩回答。
我自己的 __init__.py
文件大多数时候都是空的。特别是,我从来不会在 __init__.py
里写 from blah import *
这种语句。如果“导入这个包”意味着获取包里直接定义的各种类、函数等,那我宁愿把 blah.py
的内容直接复制到包的 __init__.py
里,然后把 blah.py
删除掉(增加源文件没有什么好处)。
如果你真的想支持 import *
这种写法(哎呀),那么使用 __all__
(尽量让这个列表里的名字少一些)可能会对控制损害有所帮助。一般来说,命名空间和明确的导入是好的东西,我强烈建议你重新考虑任何系统性绕过这两个概念的方法!-)
__all__
是个很好的东西 - 它可以帮助我们管理导入的模块,而不是自动导入所有模块。http://docs.python.org/tutorial/modules.html#importing-from-a-package
使用 __all__
和 import *
是多余的,只需要 __all__
就可以了。
我认为在 __init__.py
文件中使用 import *
来导入包的一个强大理由是,它可以让我们在不破坏现有应用的情况下,重构一个已经变成多个脚本的脚本。不过,如果你是从头开始设计一个包,最好把 __init__.py
文件留空。
例如:
foo.py - contains classes related to foo such as fooFactory, tallFoo, shortFoo
然后应用程序发展壮大,现在变成了一个完整的文件夹。
foo/
__init__.py
foofactories.py
tallFoos.py
shortfoos.py
mediumfoos.py
santaslittlehelperfoo.py
superawsomefoo.py
anotherfoo.py
这时,初始化脚本可以这样写:
__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos',
'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo']
# deprecated to keep older scripts who import this from breaking
from foo.foofactories import fooFactory
from foo.tallfoos import tallFoo
from foo.shortfoos import shortFoo
这样,写好的脚本在变更时不会出错:
from foo import fooFactory, tallFoo, shortFoo