python中_init_.py 到底有啥用?

 

1. __init__.py 是个啥?

__init__.py,这个文件名就是用来“初始化”的。在Python里,它主要用于标识一个目录是一个“包(Package)”。在项目里新建了一个文件夹,要让它成为一个可供导入的模块包,最简单的办法就是在里面加一个__init__.py。

比如,咱们有个项目结构如下:

my_project/    
├── __init__.py    
├── module1.py    
└── module2.py

想要在外部使用 my_projec t这个包时,就可以这样导入:

import my_project

有了__init__.py的存在,Python才知道my_project是一个包,而不是一个普通的文件夹。所以这个文件的基本作用就是:告诉Python,“这里是个包,可以在其他地方导入我!”

2. __init__.py 还能做些啥?

1. 模块初始化操作

假如有一个需要初始化配置的工具包,可以在__init__.py里直接搞定这些初始化工作。

# 例子:my_project/__init__.py

import os

# 初始化配置文件路径
config_file = os.path.join(os.path.dirname(__file__), 'config.yaml')
print("正在初始化配置文件……")

当一导入my_project时,config.yaml就被自动加载了。再也不用在每个子模块里重复配置路径!

2.控制子模块导入

通过在__init__.py中导入函数,可以直接在 import package_name 的时候就将所有常用的子模块或者函数导入,这样就能从包的顶级目录直接访问子模块的内容了:

 

3.包级别变量和函数的初始化

还可以在__init__.py里设置一些全局变量,或者定义一些包级别的工具函数。

 

3. __init__.py 的一些“坑”【循环导入】

什么是循环导入?

假设有两个模块module1和module2,然后在module1.py中写了这样一段代码:

# module1.py

from .module2 import some_function

  

然后又在module2.py里这样写

# module2.py

from .module1 import another_function

这就会导致Python在导入包的时候出现死循环,结果是两边互相等待对方加载,最终就会报错或者无法正常导入。 

 

4. __init__.py 和相对导入的关系

相对导入和绝对导入

__init__.py里用相对导入的语法,比如:

from .module1 import func1

看上去没问题,但等到跑module1.py这个文件时,就会发现报错了!因为相对导入的方式要求你必须从顶层包开始导入。而你直接执行module1.py,Python根本不知道它是从哪个包里来的。

建议尽量使用绝对导入,比如这样:

from my_project.module1 import func1

这样不管是直接运行module1.py,还是导入整个my_project,都不会有问题。

 

5. 还有哪些小技巧?

避免复杂逻辑:不要在__init__.py中写太复杂的业务逻辑。应该是轻量级的初始化和导入,不然以后维护起来会非常麻烦。

模块导出控制:你可以用__all__来控制从包中导出哪些模块或变量。

这样当你用 from my_project import *时,Python只会导入__all__指定的内容

__all__ = ['module1', 'module2']

 

posted @ 2024-10-12 15:12  北京测试菜鸟  阅读(48)  评论(0编辑  收藏  举报