我能把一个类定义放在__init__.py文件里吗?

20

我有一个类似于这个的类结构包。

Base类是几个独立层次结构的典型简单父类。

我的包布局如下:

__init__.py (empty)
base.py
ab.py
cd.py
ef.py

Base类放到__init__.py里而不是为了一个类创建单独的模块,这是一个好主意或好的实践吗?这样一来,我就不需要在每个模块中导入它。


3
我会将它留在base.py中,但是在__init__.py中编写类似于“from base import Base”的代码,这样您就可以直接从my_package导入“Base”,例如“from my_package import Base”。 - j-i-l
1个回答

36

将它放在base.py中是完全可以的,这样做更加灵活。还要注意__init__.py的主要用途是初始化Python包,而不是保存内容。

为避免每次导入模块都要写一遍,可以编写类似于以下代码:

# in __init__.py
from .base import Base

Base类添加到__init__.py中,这样你就可以直接从my_package导入它:

# some script
from my_package import Base

这是一种常见的方法,使对象在包级别上可用。

要了解有关__init__.py文件的更多信息,请查看文档


9
把类放在__init__.py里面有什么缺点? - user42723
1
@user42723 这样做本质上没有什么问题,但有些人可能会觉得这样做很混乱或风格不佳。关键的洞察力在于 Python 包实际上就是模块 - 它们由相同的 module 类型表示,甚至不是子类型。 - Karl Knechtel
例如,标准库直接在collections包的__init__.py中定义了一堆东西。这是一种简单的处理方式,因为collections最初只是一个简单的模块,后来才添加了collections.abc。同样,json__init__.py中定义了基于函数的主要接口,同时将支持类放到了单独的文件中。 - Karl Knechtel
@user42723 问题在于它毫无道理地对待某些类别不同于其他类别...除非你把所有的类别都放在init文件中(这种方式也会鼓励这样做)。所有东西都在一个文件中会导致通常的问题:合并困难、可读性差、找不到你要找的东西。在__init__中散布一些文件,其余的文件放在其他地方,这样很难推断一个类是否存在于一个包中,或者在大型项目中使用多个任意不同的搜索技术来查找类。 - Merk
你可能有理由对一个类进行不同的处理,但这种情况很少见...例如,一个作为包中所有其他类的基类的类可能是有意义的。 - Merk

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