关于Python中__init__.py文件的疑问与使用

init.py 是在里面写__all__=[""]用来导入包的,函数或类写在同一个包的其他文件里。 但我看了 django 的源码,他有些包,会把一些函数或者类也写在__init__.py 所以我想问,把函数或者类写在__init__.py 有什么特殊含义或者用法么?


关于Python中__init__.py文件的疑问与使用

19 回复

你在导入这个模块的时候 实际是在导入 init.py 文件


__init__.py文件是Python包(package)的核心标识。简单来说,它是一个让Python把目录识别为包的“标记文件”。它的主要作用有三个:

  1. 标识包:这是最基本的功能。只要目录里包含一个__init__.py文件(即使是空的),Python就认为这是一个包,你可以用import package_name的方式导入它。

  2. 初始化包:当包或模块被导入时,__init__.py里的代码会首先被执行。你可以在这里写一些初始化代码,比如设置包级别的变量、导入子模块,或者执行一些必要的配置。

  3. 定义__all__变量:这个变量控制着当你使用from package import *时,哪些子模块会被自动导入。它是一个字符串列表,例如__all__ = [“module1”, “module2”]

举个例子,假设你有这样一个项目结构:

my_package/
├── __init__.py
├── module_a.py
└── module_b.py

__init__.py 可以这样写:

# my_package/__init__.py

# 1. 包初始化代码
print(“正在初始化 my_package…”)
PACKAGE_VERSION = “1.0”

# 2. 便捷导入:将子模块的关键功能提升到包级别
# 这样用户可以直接用 from my_package import useful_func
from .module_a import useful_func
from .module_b import MyClass

# 3. 控制 from my_package import * 的行为
__all__ = [“useful_func”, “MyClass”, “PACKAGE_VERSION”]

用户使用起来会很方便:

import my_package # 会打印“正在初始化 my_package…”
from my_package import useful_func # 直接导入,因为__init__.py里已经导入了
print(my_package.PACKAGE_VERSION) # 可以直接访问包级变量

总结一下:空__init__.py文件让目录变成包,而写代码进去则能让你控制包的导入行为和初始化逻辑。对于现代Python(3.3+),即使目录里没有__init__.py,它也能被作为“命名空间包”导入,但如果你需要执行初始化代码或控制导入,显式地创建它仍然是标准做法。

一句话建议:把__init__.py当作你包的“主控室”,用它来管理对外的接口和初始设置。

没有,而且不推荐这样做。和普通.py 文件的唯一区别就是导入路径

没有特殊含义

all 导出仅仅是针对 from xxx import * 而已

一个文件夹包含__init__.py 就成了 Python 包,可以用 import、from… import …导入

没什么特殊的含义。
同样不建议在这里边写代码,不好组织代码。容易出现交叉引用的情况。

init.py 在 python3 里已经不需要了

有说明链接吗?


就是为了在导入的时候省事儿.

模块与包的区别,新建一个文件夹有 init 的就是包,你可以在新建的时候选择 package 看下

找到了谢谢.

严格来说是 Python 3.3 之后空的 init. py 不需要了。见 [PEP 420]( https://www.python.org/dev/peps/pep-0420/)

你可能理解错了 PEP 420

如何说?

整个 PEP 明明讨论的是 Namespace package,并不影响普通 package

我感觉我说的那句没问题,有了 namespace packages,空的 init.py 确实不需要了。但如果在某文件夹发现了 __init__py,仍然会当作是 regular package ( 3.2 及之前版本实现的 package )。

Namespace package 是 python 包分发的概念,这个 package 是代码组织的概念,无论是不是 3.2 以后都是要__init__.py ,不然你都 import 不了

实际上是能 import 的,A 目录下有个 B.py ,在 A 同级目录下是能够 import A.B 的,我一直这么写的,Python3.6

不能,Python 3.7.4

Traceback (most recent call last):
File “c.py”, line 1, in <module>
import a.b
ModuleNotFoundError: No module named ‘a’

我这里可以,Python 3.6.8 和 3.7.3



回到顶部