关于Python中__init__.py文件的疑问与使用
init.py 是在里面写__all__=[""]用来导入包的,函数或类写在同一个包的其他文件里。 但我看了 django 的源码,他有些包,会把一些函数或者类也写在__init__.py 所以我想问,把函数或者类写在__init__.py 有什么特殊含义或者用法么?
关于Python中__init__.py文件的疑问与使用
你在导入这个模块的时候 实际是在导入 init.py 文件
__init__.py文件是Python包(package)的核心标识。简单来说,它是一个让Python把目录识别为包的“标记文件”。它的主要作用有三个:
-
标识包:这是最基本的功能。只要目录里包含一个
__init__.py文件(即使是空的),Python就认为这是一个包,你可以用import package_name的方式导入它。 -
初始化包:当包或模块被导入时,
__init__.py里的代码会首先被执行。你可以在这里写一些初始化代码,比如设置包级别的变量、导入子模块,或者执行一些必要的配置。 -
定义
__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’



