Python专家编程系列: 12.Python包(package)中__init__.py的作用

0. 标题

Python专家编程系列: 12.Python包(package)中__init__.py的作用

id: 101

作者: quantgalaxy@outlook.com   
欢迎交流   

1. 什么是包(package)中的 __init__.py 文件

假设你有一个Python目录,里面有一堆Python文件,你想把它当作一个包来对待。只要在里面放一个 __init__.py 文件就行了。
Python会将该目录识别为一个包。这就像代码和Python之间的秘密握手。

__init__.py 文件可以是一个空文件。
如果你需要有些特殊的处理,也可以在里面写上一些代码。
当其他人想要使用你的包时,他们将它导入到他们的代码中,Python首先会去寻找那个神奇的 __init__.py,把它加载起来。

如果没有__init__.py, Python将无法将目录识别为包,并且您将无法使用标准的" import "语句从其中导入模块。

在旧版本的Python(3.3之前)中,必须在包中创建__init__.py文件,然后才能使用from mypackage import mymodule形式的import语句。
自3.3版和PEP 420实现以来,Python将在许多情况下隐式自动创建“命名空间包”。
这意味着__\init__.py现在通常是可选的,但它仍然有助于构建初始化代码并定义像from mypackage import *这样的语句应该如何工作。

2. __init__.py 是如何帮助创建包的

__init__.py允许您将代码组织成模块化块,使所有内容都具有超级可管理性和可重用性。
把它想象成你包的蓝图——你可以在 __init__.py中定义通用函数、变量,甚至导入其他模块,为你的包的功能建立基础。

举例看下:
让我们创建一个名为my_package的简单包来说明 __init__.py如何在my_package目录中工作。
创建一个名为__init__.py的空文件,并创建另一个名为greetings.py的文件,并编写一个名为say_hello()的函数,该函数打印“Hello, World!”

# greetings.py
def say_hello():
    print("Hello, World!")

现在,可以从my_package目录之外的任何文件导入问候模块并使用say_hello()函数。这将打印“Hello, World!”。
因为 __init__.py 使 greetings 模块可以从 my_package 命名空间中访问。

from my_package import greetings
greetings.say_hello()

# Hello, World!

更大和更复杂的包通常使用__init__.py来更好地组织代码,并运行在导入包时应该自动运行的任何初始化。
例如,您可以在 xx/__init__.py文件中添加print行(“Hi from __init__.py”)。现在,如果你导入包,它会立即运行print语句。

3. __init__.py 对 __all__ 的影响

__init__.py中定义的一个常见的东西是 __all__变量。
当用户在程序中运行导入语句时,将覆盖当用户以 “from mypackage import *”" 的形式运行import语句时应该导入的模块和函数。
默认情况下,Python不会从包中导入模块。因此,如果我们更改calculator.py文件中的第一行,从操作中导入所有内容,它将无法工作。

假设我们有一个operations包。
目录布局如下:

├── calculator.py
└── operations
    ├── divider.py
    └── multiplier.py

文件里面的实现如下:
divider.py

# operations/divider.py

class Divider:

    def divide(self, a, b):
        return a / b

multiplier.py

# operations/multiplier.py

class Multiplier:

    def multiply(self, a, b):
        return a * b

calculator.py

# calculator.py

# broken import unless we explicitly define `__all__` in `__init__.py`
from operations import *

mymultiplier = multiplier.Multiplier()
result = mymultiplier.multiply(2, 5)
print(f"2 x 5 is {result}")

mydivider = divider.Divider()
result = mydivider.divide(10, 2)
print(f"10 / 2 is {result}")

如果运行 calculator.py 文件,会触发一个错误:

Traceback (most recent call last):
  File "/Users/g/python_init_example/calculator.py", line 3, in <module>
    mymultiplier = multiplier.Multiplier()
                   ^^^^^^^^^^
NameError: name 'multiplier' is not defined

如果我们在 operations/init.py 中 添加一行:

__all__ = ['divider', 'multiplier']

上面的脚本就可以正常执行了:

2 x 5 is 10
10 / 2 is 5.0

__init__.py是创建结构化和有组织的Python包的基本构建块。
它就像一种无形的粘合剂,将您的代码粘合在一起,使其更容易管理重用和共享。
因此,简单来说,__init__.py就像是Python项目的起跑线。

4. 作者信息

作者: quantgalaxy@outlook.com   
欢迎交流   
Python包(Package)的组织结构:__init__.py的作用 本文深入探讨了Python包的组织结构,特别是__init__.py文件的核心作用。首先介绍了Python模块与包的基本概念,模块是一个.py文件,而包是一个包含多个模块的目录。接着详细解析了__init__.py文件的多重功能,包括标识包目录、初始化包代码、定义__all__变量、集中导入常用内容以及实现子包和模块的延迟加载。文章还对比了__init__.py在Python 2.x和3.x中的变化,特别是Python 3.3引入的隐式命名空间包。最后,通过实际项目示例展示了__init__.py的高级用法 阅读详情

相关推荐

还有人不知道这?Python __init__.py 文件使用

init.py的主要作用是: Python中package的标识,不能删除 定义__all__用来模糊导入 编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单) init.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件。 通常__init__.py 文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__in

m0_67575344的博客 6574

【计算机组成原理】课程设计四:控制器设计(二)

本文主要是介绍了计算机组成原理课程设计四其二,即控制器设计(二),属于计算机课程设计专栏

superiony的博客 1429

QEMU pcie config空间访问机制

而pci_host_conf/data_le_ops的定义是在hw/pci/pci-host.c里,对于0xCF8端口的处理,因为是地址选通,所以只需要在write的时候记录、read的时候返回记录的值即可。而pci_host_config_write/read_common接口,在前256Bconfig空间的模拟中,也同样是会调用这个接口,所以后续的处理都是一样的。这是真实的硬件设计,而对于QEMU+KVM的虚机场景,显然是要基于硬件实现和虚拟化的需求设计虚机访问config空间的完整流程。

leiyanjie8995的博客 1952

Ubuntu系统下主板GPU温控pwm风扇

在Linux系统下——以Ubuntu为例,配置主板sys_fan等接口连接pwm温控风扇转速根据NVIDIA GPU温度,为服务器GPU等无主动散热显卡提供散热。

罗思哲的博客 5033

离线安装PlutoSDR硬件支持包全攻略:没有MathWorks账号也能搞定MATLAB集成

本文详细介绍了在没有MathWorks账号和网络环境的情况下,如何离线安装PlutoSDR硬件支持包并实现MATLAB集成的完整解决方案。从驱动安装、设备识别到MATLAB支持包的离线部署,提供了全面的步骤指导和常见问题排查方法,特别适合高校实验室、军工单位等内网环境使用。

js777的博客 266

Frida+Objection保姆级教程:从环境搭建到实战Hook(含Wallbreaker插件使用)

本文提供了一份从零开始的Frida与Objection移动安全动态分析实战指南。详细讲解了Python环境配置、Frida-Server部署、Objection核心命令使用以及Wallbreaker插件安装与应用。通过实战案例演示如何Hook网络请求(如HttpURLConnection和OkHttp3),帮助安全研究人员快速掌握应用运行时行为分析与漏洞挖掘技能。

weixin_28318011的博客 101

Linux USB Gadget框架解析:从设备模拟到驱动开发实战

USB(通用串行总线)是现代计算机系统中应用最广泛的外设连接标准,其主从动态切换的特性使其在嵌入式系统中扮演着双重角色。与I2C、SPI等固定主从架构不同,USB设备需要同时支持主机(Host)和从机(Device)两种模式,这催生了Linux内核中独特的USB Gadget框架。该框架通过分层设计,将硬件控制器驱动(UDC)、功能逻辑(Function)和配置管理(Configfs)解耦,实现了灵活的设备模拟能力。在工程实践中,开发者可以利用Gadget框架快速实现U盘、网络适配器、串口转换器等常见USB

weixin_28007513的博客 561

基于NB-IoT的智慧路灯监控系统(NB-IoT专栏—实战篇1:项目简介)

基于NB-IoT技术的城市道路智慧路灯监控系统,在每个照明节点上安装一个集成了NB-IoT模组的单灯控制器,单灯控制器再经运营商的网络,与路灯控制平台实现双向通信,路灯控制平台直接对每个灯进行控制,包括开关灯控制、光照检测、自动调节明暗、电耗分析等操作。

不脱发的程序猿 5万+

柔性电极材料新突破:清华团队实现0.1mV级脑信号采集精度

清华团队的 0.1mV 级柔性电极突破,不仅是材料科学与神经工程的跨界胜利,更标志着脑机接口从 “信号采集” 向 “神经交互” 的范式转变。当电极与脑组织实现 “柔性共生”,人类首次拥有了窥探大脑微观电活动的 “精密探头”,这既是神经疾病诊疗的里程碑,更是人机融合时代的新起点。随着技术标准化与产业生态的完善,这场始于实验室的 “柔性革命”,正加速向临床病房、智能工厂、消费电子等场景渗透,为脑机接口的大规模应用铺设 “柔性跑道”。:当柔性电极实现 “神经信号的无损捕捉”,如何平衡技术创新与伦理边界?

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 2943

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: Python专家编程系列: 11.为什么在python使用__name__ == __main__
下一篇: backtesting.py介绍和相关资料
novowindx
博客等级 码龄4年 107粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

novowindx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值