Python中的`__init__.py`到底有啥用?如何用?一文搞懂!

大家好,在Python项目开发中,你经常会看到__init__.py文件,但到底它有啥用呢?今天我们就从原理到实际案例,深入浅出地为你揭开__init__.py的神秘面纱,帮你彻底理解它的作用!

为什么__init__.py很重要?

在Python中,__init__.py 文件是一个特殊文件,它的存在与否决定了Python如何处理包含它的目录。具体来说,__init__.py 文件的作用主要有以下几点:

  1. 标记目录为Python包(Package)
    • 当一个目录中存在__init__.py文件时,Python会将这个目录视为一个Python包。这意味着该目录下的Python模块(即.py文件)可以被导入(import)使用。如果没有__init__.py文件,则该目录不会被视为Python包,其内部的模块也就无法被导入。
  2. 初始化包
    • __init__.py 文件可以包含Python代码。当包被首次导入时,这些代码会被自动执行。这通常用于包的初始化操作,比如设置包级别的变量、注册包内的模块或类、执行必要的检查等。
  3. 控制从包中导入的模块
    • 通过在__init__.py文件中定义__all__变量,可以控制当使用from package import *时,哪些模块或子包会被导入。__all__应该是一个包含模块名(字符串)的列表。
  4. 命名空间包
    • 在Python 3.3及更高版本中,引入了命名空间包(Namespace Packages)的概念。与传统的包不同,命名空间包不需要在每个目录中都有__init__.py文件。它们主要用于跨多个位置或项目分发包的一部分。但是,即使在这种情况下,__init__.py文件仍然可以用于传统包的初始化目的。
  5. 兼容旧版Python
    • 对于仍在使用Python 2.x版本的项目,__init__.py文件是必需的,因为Python 2没有命名空间包的概念。

具体案例代码

接下来,我们通过几个案例代码来看看__init__.py的实际应用。

1. 声明一个包

首先,假设我们有这样一个文件结构:

my_project/├── my_package/│   ├── __init__.py│   ├── module_a.py│   └── module_b.py└── main.py

这个my_package就是一个包,而module_a.pymodule_b.py是包中的模块。__init__.py的存在告诉Python,这个文件夹可以作为包来使用。于是我们可以在main.py中这样导入模块:

# main.py
from my_package import module_a, module_bmodule_a.function_a()
module_b.function_b()

如果__init__.py不存在,那么Python会无法识别my_package为包,导入将会失败。

2. 在__init__.py中导入子模块

我们可以在__init__.py中控制导入行为,简化模块的使用。比如,我们可以这样写__init__.py

# __init__.py
from .module_a import function_a
from .module_b import function_b

这样做的好处是,在main.py中,我们可以更加简洁地导入模块的功能:

# main.py
from my_package import function_a, function_bfunction_a()
function_b()

通过这种方式,__init__.py帮我们创建了一个更方便的包接口,使得用户无需关注包的内部结构,直接使用核心功能。

3. 执行初始化代码

假设我们有个需求,每次导入包时都要初始化一个数据库连接,可以在__init__.py中加入初始化代码:

# __init__.py
def init_db():print("数据库初始化")init_db()

当我们导入这个包时,init_db()函数会自动执行:

# main.py
import my_package  # 输出:数据库初始化

这样,在包被导入时,任何必要的初始化操作都可以通过__init__.py自动完成。

__init__.py就像是Python包的守门人,它不仅负责声明包的存在,还可以定制包的导入行为,甚至可以执行初始化操作。理解了它,你可以更灵活地组织代码,设计更优雅的包结构。

随着Python的发展,特别是Python 3的普及,以及隐式命名空间包(Implicit Namespace Packages)的引入,__init__.py文件的使用在某些情况下可能变得不那么必要。然而,了解它的作用仍然对于理解和维护现有的Python项目非常重要。在Python 3中,如果你只是想将一组模块组织在一起,而不需要执行初始化代码或控制导入,可以省略__init__.py文件,转而使用命名空间包。但请注意,这可能会影响包的某些高级用法,如相对导入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/428624.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频

Android早期的MediaPlayer控件对于网络视频的兼容性很差,所以后来单独推出了Exoplayer库增强支持网络视频,在《Android Studio开发实战:从零基础到App上线(第3版)》一书第14章的“14.3.3 新型播放器ExoPlayer”就详细介绍了Exoplayer库的详细…

【Python】从基础到进阶(八):文件操作与上下文管理

🔥 个人主页:空白诗 文章目录 一、引言二、Python文件操作基础1. 打开文件2. 读取文件3. 写入文件4. 文件指针定位 三、上下文管理1. 使用with管理文件2. 自定义上下文管理器 四、文件操作的最佳实践五、案例:日志文件管理1. 需求分析2. 实现…

OpenCV结构分析与形状描述符(24)检测两个旋转矩形之间是否相交的一个函数rotatedRectangleIntersection()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 测两个旋转矩形之间是否存在交集。 如果存在交集,则还返回交集区域的顶点。 下面是一些交集配置的例子。斜线图案表示交集区域&#…

从边缘设备到云端平台,合宙DTURTU打造无缝物联网解决方案

如今,物联网(IoT)技术飞速发展,万物互联的时代已然到来,那么,高效、稳定地连接边缘设备与云端平台,实现数据的实时采集、传输与处理,就成为了推动物联网应用落地的关键。 DTU&#…

以root用户登陆ubuntu的桌面环境

去我的个人博客观看,观感更佳哦,😙😙 前言 在学习Linux的时候,经常都需要使用sudo权限来对配置文件进行修改,常用的方法就是用vim编辑器在命令行界面进行修改,比如sudo vim /etc/profile&#…

【深度学习】(1)--神经网络

文章目录 深度学习神经网络1. 感知器2. 多层感知器偏置 3. 神经网络的构造4. 模型训练损失函数 总结 深度学习 深度学习(DL, Deep Learning)是机器学习(ML, Machine Learning)领域中一个新的研究方向。 从上方的内容包含结果,我们可以知道,在学习深度学…

【Linux】解锁系统编程奥秘,高效文件IO的实战技巧

文件 1. 知识铺垫2. C文件I/O2.1. C文件接口2.2 fopen()与重定向2.3. 当前路径2.4. stdin、stdout、stderr 3. 系统文件I/O3.1. 前言3.2. open3.2.1. flags</h3>3.2.2. mode</h3>3.2.3. 返回值fd 3.3. write</h2>3.4. read3.5. close</h2>3.6. lseek&l…

面试经典150题——删除有序数组中的重复项

目录 题目链接&#xff1a;26. 删除有序数组中的重复项 - 力扣&#xff08;LeetCode&#xff09; 题目描述 判题标准: 示例 提示&#xff1a; 解法一&#xff1a;双指针 Java写法&#xff1a; 运行时间 C写法&#xff1a; 运行时间 论屎山代码是如何出现的 时间复杂…

感知笔记2:ROS 视觉 - 沿线行走

如何在 ROS 中使用 OpenCV如何跟踪线路如何根据颜色查找不同元素跟踪多条路径并做出决定为线路跟踪创建基本的 PID 在本章中&#xff0c;您将学习如何使用 ROS 中最基本、最强大的感知工具&#xff1a;OpenCV。 OpenCV 是最广泛、最完整的图像识别库。有了​​它&#xff0c;…

Docker实操:安装MySQL5.7详解(保姆级教程)

介绍 Docker 中文网址: https://www.dockerdocs.cn Docker Hub官方网址&#xff1a;https://hub.docker.com Docker Hub中MySQL介绍&#xff1a;https://hub.docker.com/_/mysql ​ 切换到“Tags”页面&#xff0c;复制指定的MySQL版本拉取命令&#xff0c;例如 &#xff1a…

uv-ui组件的使用——自定义输入框的样式

一、官网的使用 二、自定义修改样式 我是在小程序中使用此组件 想要自定义修改样式的话&#xff0c;需要placeholderClass加上 placeholderStyle配合使用 tip1&#xff1a;单独使用placeholderClass&#xff0c;他只会第一次渲染时生效&#xff0c;输入文字再清除后就不生效…

十六,Spring Boot 整合 Druid 以及使用 Druid 监控功能

十六&#xff0c;Spring Boot 整合 Druid 以及使用 Druid 监控功能 文章目录 十六&#xff0c;Spring Boot 整合 Druid 以及使用 Druid 监控功能1. Druid 的基本介绍2. 准备工作&#xff1a;3. Druid 监控功能3.1 Druid 监控功能 —— Web 关联监控3.2 Druid 监控功能 —— SQL…

(蓝桥杯)STM32G431RBT6(TIM4-PWM)

一、基础配置 这个auto-reload preload是自动重装载值&#xff0c;因为我们想让他每改变一个占空比&#xff0c;至少出现一次周期 Counter Period(Autoreload Regisiter)这个设值为10000&#xff0c;那么就相当于它的周期是10000 脉冲宽度可以设置为占周期的一半&#xff0c;那…

Python酷库之旅-第三方库Pandas(123)

目录 一、用法精讲 546、pandas.DataFrame.ffill方法 546-1、语法 546-2、参数 546-3、功能 546-4、返回值 546-5、说明 546-6、用法 546-6-1、数据准备 546-6-2、代码示例 546-6-3、结果输出 547、pandas.DataFrame.fillna方法 547-1、语法 547-2、参数 547-3、…

opencv图像透视处理

引言 在图像处理与计算机视觉领域&#xff0c;透视变换&#xff08;Perspective Transformation&#xff09;是一种重要的图像校正技术&#xff0c;它允许我们根据图像中已知的四个点&#xff08;通常是矩形的四个角&#xff09;和目标位置的四个点&#xff0c;将图像从一个视…

Ubuntu 与Uboot网络共享资源

1、NFS 1.1 Ubuntu 下 NFS 服务开启 sudo apt-get install nfs-kernel-server rpcbind 等待安装完成&#xff0c;安装完成以后在用户根目录下创建一个名为“Linux”的文件夹&#xff0c;以后所有 的东西都放到这个“Linux”文件夹里面&#xff0c;在“Linux”文件夹里面新建…

[Simpfun游戏云1]搭建MC Java+基岩互通生存游戏服务器

众所周知&#xff0c;MC有多个客户端&#xff0c;像常见的比如Java Edition和基岩等&#xff0c;这就导致&#xff0c;比如我知道一个超级好玩的JE服务器&#xff0c;但我又想使用基岩版来玩&#xff0c;肯定是不行的&#xff0c;因为通讯协议不一样。 这就有一些人才发明了多…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(四)-搜索

搜索 搜索内容比较多&#xff0c;onesearch分成两部分&#xff0c;第一部分&#xff0c;Query构建&#xff0c;其中包括搜索词设置&#xff0c;设置返回字段&#xff0c;filter&#xff0c;高亮&#xff1b;第二部分分页和排序。第一部分是映射引擎负责&#xff0c;映射通用表…

常见中间件漏洞靶场(tomcat)

1.CVE-2017-12615 开启环境 查看端口 查看IP 在哥斯拉里生成一个木马 访问页面修改文件后缀和文件内容 放包拿去连接 2.后台弱⼝令部署war包 打开环境 将前边的1.jsp压缩成1.zip然后改名为1.war 访问页面进行上传 在拿去连接 3.CVE-2020-1938 打开环境 访问一下 来到kali …

错题集锦之C语言

直接寻址和立即寻址 算法的又穷性是指算法程序的运行时间是有限的 未经赋值的全局变量值不确定 集成测试是为了发现概要设计的错误 自然连接要求两个关系中进行比较的是相同的属性&#xff0c;并且进行等值连接&#xff0c;在结果中还要把重复的属性列去掉 赋值运算符 赋值…