如何编写好的/正确的包 __init__.py 文件
- 2025-04-15 09:18:00
- admin 原创
- 25
问题描述:
我的包具有以下结构:
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__
使用?
解决方案 1:
__all__
非常好 - 它有助于指导导入语句,而无需自动导入模块
http://docs.python.org/tutorial/modules.html#importing-from-a-package
使用__all__
和import *
是多余的,只__all__
需要
import *
我认为使用in导入包的最有力理由之一__init__.py
是能够在不破坏现有应用程序的情况下重构已发展为多个脚本的脚本。但如果您是从头开始设计包,我认为最好将__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
解决方案 2:
我自己的__init__.py
文件经常是空的。特别是,我从来不会把当作包from blah import *
的一部分__init__.py
——如果“导入包”意味着把所有类型的类、函数等等都直接定义成包的一部分,那么我会把 的内容从词法上复制blah.py
到包中__init__.py
,然后再移除blah.py
(源文件的倍增在这里毫无意义)。
如果你坚持支持这些import *
惯用法(呃),那么使用__all__
(尽可能少地列出名称)或许有助于控制损害。总的来说,命名空间和显式导入是好东西,我强烈建议你重新考虑任何基于系统性地绕过其中一个或两个概念的方法!-)
解决方案 3:
您__init__.py
应该有一个文档字符串。
虽然所有功能都是在模块和子包中实现的,但包的文档字符串才是记录从哪里开始的地方。例如,考虑一下Pythonemail
包。包文档是一份介绍,描述了包的目的、背景以及包中各个组件如何协同工作。如果您使用 Sphinx 或其他包自动从文档字符串生成文档,那么包的文档字符串正是描述此类介绍的最佳位置。
对于任何其他内容,请参阅firecrow和Alex Martelli的精彩回答。
扫码咨询,免费领取项目管理大礼包!