当前位置: 首页 > news >正文

Python--包/模块/第三方库

Python–包/模块/第三方库

@mengyb

1、包与模块

  • Python 中除了函数库以外,还有非常多且优秀的第三方库、包、模块。
  • 模块(module) : 以.py为后缀的文件,称之为 模块
  • 包(package) : 即文件夹,传统包里有一个__init__.py文件。可以为空文件,但一定要有该文件,它是包的标志性文件,在需要情况下可以在里面进行一些包的初始化工作。
  • 库 : 一定功能的代码集合, 如os、sys、math等

库->包->模块,是从大到小的层级关系:
库: 一个库可能由多个包和模块组成
包:一个包可能由多个模块组成
模块:一堆函数、类、变量的集合

1.1、__init__.py作用

__ init __.py 定义了包的「公共接口」,隐藏内部模块结构,让调用者更方便。(注意,Python3.3之后发生了变化)

1.1.1、示例
my_project/ ├── main.py └── my_package/ ├── __init__.py ├── core/ │ ├── __init__.py │ ├── engine.py │ └── parser.py └── utils/ ├── __init__.py └── helper.py
  • 开始使用
# (在 __init__.py 中集中管理):# my_package/__init__.pyfrom.core.engineimportEnginefrom.core.parserimportParserfrom.utils.helperimportformat_data# main.py 可以直接使用,不需要再去找frommy_packageimportEngine,Parser,format_data# 简单清晰!

这种方式对使用者非常友好,你只需要暴露一个经过设计的、干净的 API 入口。

1.1.2、使用__all__控制from package import *的行为

当用户使用from my_package import *时,Python 默认不会导入所有子模块。你可以通过__init__.py中的__all__变量来显式指定允许被导入的模块列表。

# my_package/__init__.py# 定义 "from my_package import *" 时,会导入哪些模块__all__=["Engine","Parser","format_data"]

这是一种明确的 API 声明,可以防止意外暴露内部实现细节。

1.1.3、特殊用法:只运行一次的“单例”初始化

因为init.py 在包第一次被导入时只执行一次,所以它非常适合用来创建“单例模式”的对象。

# my_package/__init__.pyclassDatabaseConnection:def__init__(self):self.connected=True# 在包导入时创建一个唯一的数据库连接对象db=DatabaseConnection()# 对外暴露创建好的实例__all__=['db']

这样,无论在项目的哪个地方导入 my_package.db,拿到的都是同一个对象。

1.1.4、注意事项
  1. 空文件没问题,但推荐利用它:即使你的__init__.py是空的,也请保留它。这能确保你的代码在所有 Python 版本下都被正确识别为包。
  2. __init__.py当作包的“门面”:使用相对导入(from .module import something)把内部模块的关键函数和类“提升”到包的最顶层。
  3. 谨慎编写初始化代码:记住,这段代码在包被导入时就会运行。不要在__init__.py中执行耗时过长的操作,否则会拖慢首次导入的速度。
  4. 保持__init__.py简洁:它主要用于导入和协调,不要在里面写太多复杂的业务逻辑。业务逻辑应该放在模块(.py文件)中。
  5. 使用__all__明确 API:这可以提升代码的可读性,也是一种良好的文档化实践。
1.1.5、总结
  • 让python知道这是一个[包]

    • 只要目录中有__init__.py文件,即使是空的,python也会把这个目录当成包,允许从里面导入模块
  • 是包的“入口文件”,当包被导入时,其中的代码会优先执行

  • 主要用于“暴露 API”,简化用户的导入路径,并提供包级别的初始化

    • __ init __.py中明确功能是谁,你直接去就行了。
    • __ init __.py定义了包的「公共接口」,隐藏内部模块结构,让调用者更方便。
  • 初始化全局配置

    • 如数据库连接的引入,适合单例模式
  • 控制隐私,禁止乱翻仓库

    • 引入包时如果用到*了,则必须在__init__中用all声明公开接口,,否则会报错
    • 作用:明确包的对外接口,避免内部实现被误用,就像给仓库加了「员工专用」门禁。

2、创建模块

# math_tools.pydefadd(a:int,b:int)->int:returna+bdefdecrement(a:int,b:int)->int:returna-bif__name__=="__main__":print("测试模块:",add(3,7))

3、导入模块

3.1、基本语法

# 导入整个模块importmodule_name# 导入模块的一个fun_name函数frommodule_nameimportfun_name# 导入整个模块,并未模块命名为alias_nameimportmodule_nameasalias_name# 导入所有 (不推荐)frommodule_nameimport*

3.2、示例

importmath_toolsprint(math_tools.add(3,5))frommath_toolsimportdecrementprint(decrement(5,2))importmath_toolsasmtprint(mt.add(3,2))frommath_toolsimport*print(add(1,2))

3.3、模块的__name__属性

  • 当模块被直接运行时,__name__"__main__"
  • 当模块被导入时,__name__为模块名。
# 直接运行模块时执行测试代码if__name__=="__main__":print("模块测试通过")

4、包(package)

包是一个包含多个模块的目录,必须包含一个__init__.py文件(可以是空文件),用于标识当前目录是一个包。

4.1、包结构

my_package/ ├── __init__.py ├── module1.py └── subpackage/ ├── __init__.py └── module2.py

4.2、包的引入方式

# 导入包中的模块frommy_packageimportmodule1print(module1.fun())# 导入子包中的模块frommy_package.subpackageimportmodule2print(module2.fun())# 在 __init__.py 中预先导入(可选)# my_package/__init__.pyfrom.module1importfunc

4.3、相对导入(包内部使用)

在包内部的模块中,可以使用相对路径导入其他模块:

# module2.py(位于subpackage中)from..module1importfunc# 从上级目录导入

4.4、相关函数与工具

4.4.1、重新加载模块importlib.reload()(适用于调试):
importimportlib importlib.reload(math_tools)
4.4.2、 动态导入模块(较少使用):__import__()
module_name="math_tools"math_tools=__import__(module_name)
4.4.3、sys.path

查看模块搜索路径或添加自定义路径:

importsys sys.path.append("/path/to/module_directory")

4.5、示例

4.5.1、结构
my_package/ ├── __init__.py ├── utils.py └── sub_package/ ├── __init__.py └── sort.py
4.5.2、utils.py
defadd(a:int,b:int)->int:returna+b
4.5.3、sort.py
defarea(a:int)->double:returna**2*3.14

4.5.4、在外部使用包

frommy_package.utilsimportaddfrommy_package.sub_packageimportareaprint(add(3,3))print(area(3))

4.5.5、问题处理

  1. 路径问题:模块不在当前目录时,手动添加路径:
importsys sys.path.append("/path/to/my_package")
  1. 循环导入:避免模块A导入模块B,同时模块B导入模块A。

解决方法:将导入语句移到函数内部或重构代码。

  1. __init__.py的作用:
  • 标识目录为包。
  • 定义__all__变量(如__all__ = ["module1"])控制from package import *的行为。
  • 执行包级别的初始化代码。
  1. 绝对导入 vs 相对导入
  • 绝对导入:from my_package.module import func
  • 相对导入:from .submodule import func(仅限包内部)
  1. 模块缓存:Python会缓存导入的模块(sys.modules),重复导入时直接使用缓存。

5、常见问题

  • ModuleNotFoundError:检查路径或包结构。
  • ImportError:确认导入语句是否正确,避免循环导入。
  • AttributeError:确保模块中存在被导入的属性。
http://www.cnnetsun.cn/news/3721456.html

相关文章:

  • 仿BOSS招聘平台实现(5)
  • MATLAB大型方程组求解:LU、QR与Cholesky分解原理与工程实战
  • 如何快速掌握小红书数据采集:Python开发者的完整指南
  • 3D打印技术如何为视障儿童创造可触摸的教育世界
  • STM32 ADC从原理到实战:高精度数据采集与DMA应用详解
  • XSS主动防御:构建实时监控与响应系统的工程实践
  • 整理抖音长视频要点太慢不会梳理?试试实用的抖音视频总结方法
  • 物联网设备安全连接方案:PIC18与A5000硬件加密实践
  • 西门子PLC与组态王在水泥生产线称重控制中的应用
  • 上海、安徽、浙江、江苏制造业智能仓储服务商选型指南与主流方案解析
  • 自适应遗传算法在分布式电源优化配置中的应用
  • 03-特性与参数
  • dvwa之weak session ids
  • 瓷砖一线高端品牌金丝玉玛,一块K金砖为什么让人排队看
  • Simulink与CarSim联合仿真:驾驶员模型方向盘转角控制全解析
  • c语言学习:循环嵌套与数组
  • 储能电池一次调频容量配置与经济性优化
  • 拓扑排序算法详解:从原理到实战,掌握任务调度与依赖解析
  • 基于控制屏障函数的TAC安全控制方法与实践
  • MVC、MVP与MVVM架构演进解析与应用场景
  • C++ Vector核心机制与性能优化实战指南
  • 基于行空板与图灵API构建桌面智能语音助手:软硬件结合实践指南
  • 物联网设备超低功耗方案:NBM7100A与STM32L081CB组合应用
  • 试了几款AI代码审计工具后,说点真实感受
  • 项目中的企业审核
  • Tec-2实验平台入门:微程序控制器原理与计算机组成实践
  • STM32入门指南:从芯片选型到开发环境搭建与第一个工程实践
  • machine 同轴度公差带
  • 网络打印机安全风险剖析:从PJL/PostScript渗透到内网防护实践
  • 天辛大师发问互联网精神,AI如何解决厄尔尼诺现象