人工智能之编程基础 Python 入门:第九章 模块与包

人工智能之编程基础 Python 入门

第九章 模块与包


@

目录
  • 人工智能之编程基础 Python 入门
  • 前言
  • 模块
    • 1. 模块的基本概念
      • 什么是模块?
    • 2. 导入模块
      • 1. import 语句
      • 2. from ... import ...
      • 3. from ... import *
      • 4. import ... as ...
    • 3. 模块搜索路径
    • 4. __name____main__
    • 5. 标准库模块示例
    • 6. 第三方模块
    • 7. 模块的属性和函数
      • 查看模块内容
      • 动态导入
    • 8. 模块的最佳实践
      • 1. 模块命名
      • 2. 模块结构
      • 3. __all__ 变量
    • 9. 常见问题和解决方案
      • 1. 循环导入问题
      • 2. 模块重新加载
      • 3. 隐藏模块
    • 1. 包的基本概念
      • 什么是包?
      • 包 vs 模块
    • 2. 创建包
      • 基本结构
      • __init__.py 文件的作用
    • 3. 包的导入方式
      • 1. 导入整个包
      • 2. 导入包中的特定模块
      • 3. 导入包中的特定函数/类
      • 4. 使用别名
    • 4. 相对导入 vs 绝对导入
      • 绝对导入(推荐)
      • 相对导入(在包内部使用)
    • 5. 实际项目结构示例
      • 典型的项目结构
      • 使用示例
    • 6. __init__.py 的高级用法
      • 1. 精简导入接口
      • 2. 延迟导入(按需加载)
      • 3. 版本和元数据管理
    • 7. 包的发布和安装
      • 1. 创建 setup.py
      • 2. 安装本地包
      • 3. 发布到 PyPI
    • 8. 常见问题和解决方案
      • 1. ModuleNotFoundError
      • 2. 相对导入错误
      • 3. 循环导入
    • 9. 最佳实践
      • 1. 包设计原则
      • 2. 命名规范
      • 3. 文档和测试
      • 4. 版本控制
  • 总结
  • 资料关注


前言

本章节主要学习python模块与包,同样也会涉及到特殊变量__name__变量__main__变量、__all__变量和__init__.py文件


模块

在 Python 中,模块(Module) 是组织代码的基本单元。一个模块就是一个包含 Python 定义和语句的文件,其文件名就是模块名加上 .py 后缀。


1. 模块的基本概念

什么是模块?

  • 一个 .py 文件就是一个模块
  • 模块可以包含函数、类、变量和可执行代码
  • 模块有助于代码的组织、重用和命名空间管理
# math_utils.py (模块文件)
def add(a, b):return a + bdef multiply(a, b):return a * bPI = 3.14159

2. 导入模块

1. import 语句

# 导入整个模块
import math_utilsresult = math_utils.add(3, 4)  # 使用模块中的函数
print(math_utils.PI)           # 使用模块中的变量

2. from ... import ...

# 导入特定函数/变量
from math_utils import add, multiply, PIresult = add(3, 4)     # 直接使用,无需模块前缀
area = PI * 5 ** 2

3. from ... import *

# 导入所有公共名称(不推荐)
from math_utils import *result = add(3, 4)     # 可以直接使用

注意​:这种方式可能导致命名冲突,建议明确导入所需内容

4. import ... as ...

# 给模块起别名
import math_utils as mu
import numpy as np
import pandas as pdresult = mu.add(3, 4)

3. 模块搜索路径

Python 在导入模块时会按以下顺序搜索:

  1. 当前目录
  2. PYTHONPATH 环境变量指定的目录
  3. 标准库目录
  4. 第三方包安装目录​(如 site-packages)

查看搜索路径:

import sys
print(sys.path)

添加自定义路径:

import sys
sys.path.append('/path/to/my/modules')

4. __name____main__

每个模块都有一个内置变量 __name__

# calculator.py
def main():print("Calculator module")result = add(5, 3)print(f"5 + 3 = {result}")if __name__ == "__main__":main()  # 只有直接运行此文件时才执行
else:print(f"模块 {__name__} 被导入")
  • 当模块被导入时:__name__ 等于模块名(如 'calculator'
  • 当模块被直接运行时:__name__ 等于 '__main__'

5. 标准库模块示例

Python 自带丰富的标准库模块:

# 数学运算
import math
print(math.sqrt(16))  # 4.0# 随机数
import random
print(random.randint(1, 10))# 日期时间
import datetime
now = datetime.datetime.now()# 文件操作
import os
import shutil# 正则表达式
import re
pattern = re.compile(r'\d+')# 数据序列化
import json
data = json.loads('{"name": "Alice"}')# 网络请求
import urllib.request

6. 第三方模块

使用 pip 安装第三方模块:

# 安装模块
pip install requests
pip install numpy
pip install pandas# 查看已安装的模块
pip list# 导出依赖
pip freeze > requirements.txt

使用第三方模块:

import requests
response = requests.get('https://api.github.com/users/octocat')
print(response.json())

7. 模块的属性和函数

查看模块内容

import math# 查看模块的所有属性和方法
print(dir(math))# 查看模块信息
print(help(math))# 查看特定函数的帮助
help(math.sin)

动态导入

# 使用 __import__()
module_name = "math"
math_module = __import__(module_name)# 使用 importlib (推荐)
import importlib
json_module = importlib.import_module("json")

8. 模块的最佳实践

1. 模块命名

  • 使用小写字母
  • 使用下划线分隔单词
  • 避免与标准库模块同名
  • 不要使用特殊字符

✅ 好的命名:data_processor.py, utils.py
❌ 不好的命名:DataProcessor.py, my-module.py

2. 模块结构

"""
模块文档字符串 - 描述模块的功能
"""# 1. 导入标准库
import os
import sys
from datetime import datetime# 2. 导入第三方库
import requests# 3. 导入本地模块
from . import local_module# 常量
DEFAULT_TIMEOUT = 30
MAX_RETRIES = 3# 函数和类定义
def utility_function():passclass UtilityClass:pass# 主程序入口(可选)
if __name__ == "__main__":pass

3. __all__ 变量

控制 from module import * 的行为:

# my_module.py
def public_function():passdef _private_function():  # 下划线开头表示私有passclass PublicClass:pass__all__ = ['public_function', 'PublicClass']  # 只允许导出这些

9. 常见问题和解决方案

1. 循环导入问题

# file1.py
from file2 import func_bdef func_a():func_b()# file2.py  
from file1 import func_a  # 循环导入!def func_b():func_a()

解决方案​:

  • 重构代码,消除循环依赖
  • 在函数内部导入
  • 使用字符串导入(延迟导入)
# 解决方案:在函数内部导入
def func_b():from file1 import func_afunc_a()

2. 模块重新加载

import importlib
import my_module# 修改了 my_module.py 后重新加载
importlib.reload(my_module)

3. 隐藏模块

创建隐藏模块(以 _ 开头):

# _internal.py
def secret_function():pass# 在 __init__.py 中不导出
__all__ = []  # 不包含 _internal

在 Python 中,包(Package) 是一种组织和管理多个相关模块的机制。它允许你将功能相关的模块组织在一起,形成一个层次化的结构,使大型项目更易于维护和管理。


1. 包的基本概念

什么是包?

  • 包是一个包含多个模块的目录
  • 包必须包含一个特殊的文件 __init__.py(Python 3.3+ 可选,但强烈建议保留)
  • 包可以包含子包,形成层次结构

包 vs 模块

模块
一个 .py 文件 一个包含模块的目录
math.py mypackage/ 目录
import math import mypackage

2. 创建包

基本结构

mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/├── __init__.py└── module3.py

__init__.py 文件的作用

# mypackage/__init__.py
"""
这是 mypackage 包的初始化文件
"""# 1. 标识目录为 Python 包
# 2. 包的初始化代码
print("mypackage 正在加载...")# 3. 控制导入行为
__all__ = ['module1', 'module2', 'subpackage']# 4. 导入常用内容,方便用户使用
from .module1 import important_function
from .module2 import AnotherClass# 5. 定义包级变量
__version__ = "1.0.0"
__author__ = "Your Name"

3. 包的导入方式

1. 导入整个包

import mypackage# 使用包中的内容
mypackage.module1.some_function()
instance = mypackage.subpackage.module3.SomeClass()

2. 导入包中的特定模块

from mypackage import module1
from mypackage.subpackage import module3result = module1.process_data()
obj = module3.create_object()

3. 导入包中的特定函数/类

from mypackage.module1 import process_data, DataProcessor
from mypackage.subpackage.module3 import create_object# 直接使用
data = process_data("input.txt")
processor = DataProcessor()

4. 使用别名

import mypackage as mp
from mypackage import module1 as m1result = mp.module2.analyze()

4. 相对导入 vs 绝对导入

绝对导入(推荐)

# 在 mypackage/subpackage/module3.py 中
from mypackage.module1 import helper_function
from mypackage.utils import config

相对导入(在包内部使用)

# 在 mypackage/subpackage/module3.py 中
from ..module1 import helper_function    # 上一级目录
from ..utils import config               # 上一级的 utils 模块
from . import local_module               # 同级目录

相对导入规则​:

  • . 表示当前包
  • .. 表示父包
  • ... 表示祖父包

5. 实际项目结构示例

典型的项目结构

project/
├── main.py
├── requirements.txt
└── myapp/├── __init__.py├── config.py├── models/│   ├── __init__.py│   ├── user.py│   └── product.py├── services/│   ├── __init__.py│   ├── user_service.py│   └── order_service.py├── utils/│   ├── __init__.py│   ├── database.py│   └── helpers.py└── api/├── __init__.py└── routes.py

使用示例

# main.py
from myapp.services.user_service import create_user
from myapp.models.user import User
from myapp import config# 创建用户
user_data = {"name": "Alice", "email": "alice@example.com"}
user = create_user(user_data)print(f"创建用户: {user.name}")
# myapp/services/user_service.py
from myapp.models.user import User
from myapp.utils.database import save_to_dbdef create_user(user_data):user = User(**user_data)save_to_db(user)return user

6. __init__.py 的高级用法

1. 精简导入接口

# mypackage/__init__.py
"""mypackage 主要接口"""from .module1 import CoreProcessor
from .module2 import DataAnalyzer
from .utils.helpers import format_output__all__ = ['CoreProcessor', 'DataAnalyzer', 'format_output']# 现在用户可以这样使用:
# from mypackage import CoreProcessor, DataAnalyzer

2. 延迟导入(按需加载)

# mypackage/__init__.py
class LazyLoader:def __init__(self, module_name, attribute_name=None):self.module_name = module_nameself.attribute_name = attribute_nameself._module = Nonedef __getattr__(self, name):if self._module is None:self._module = __import__(self.module_name, fromlist=[''])if self.attribute_name:return getattr(self._module, self.attribute_name)return getattr(self._module, name)# 使用
heavy_module = LazyLoader('mypackage.heavy_operations')

3. 版本和元数据管理

# mypackage/__init__.py
__version__ = "2.1.0"
__author__ = "Your Name"
__email__ = "your.email@example.com"
__license__ = "MIT"# 可以通过以下方式访问
# import mypackage
# print(mypackage.__version__)

7. 包的发布和安装

1. 创建 setup.py

# setup.py
from setuptools import setup, find_packagessetup(name="mypackage",version="1.0.0",packages=find_packages(),install_requires=["requests>=2.25.0","numpy>=1.19.0",],author="Your Name",author_email="your.email@example.com",description="A sample Python package",python_requires=">=3.6",
)

2. 安装本地包

# 开发模式安装(修改代码立即生效)
pip install -e .# 正常安装
pip install .

3. 发布到 PyPI

# 安装打包工具
pip install build twine# 创建分发包
python -m build# 上传到 PyPI
twine upload dist/*

8. 常见问题和解决方案

1. ModuleNotFoundError

ModuleNotFoundError: No module named 'mypackage'

解决方案​:

# 方法1:添加到 sys.path
import sys
sys.path.append('/path/to/parent/directory')# 方法2:使用 PYTHONPATH 环境变量
export PYTHONPATH="${PYTHONPATH}:/path/to/parent/directory"# 方法3:正确安装包
pip install -e /path/to/package

2. 相对导入错误

# 错误:尝试在脚本中直接运行包含相对导入的文件
# ValueError: attempted relative import with no known parent package

解决方案​:

# 正确的运行方式
python -m mypackage.module_name# 而不是
python mypackage/module_name.py

3. 循环导入

# file1.py
from .file2 import func_b# file2.py  
from .file1 import func_a  # 循环导入!

解决方案​:

  • 重构代码结构
  • 在函数内部导入
  • 使用字符串导入
# file2.py
def func_b():from .file1 import func_a  # 延迟导入return func_a()

9. 最佳实践

1. 包设计原则

  • 单一职责​:每个包应该有明确的功能定位
  • 高内聚​:包内的模块应该紧密相关
  • 低耦合​:包之间依赖应该最小化
  • 清晰的接口​:通过 __init__.py 提供清晰的公共 API

2. 命名规范

  • 使用小写字母
  • 使用下划线分隔单词
  • 避免与标准库冲突
  • 名称应该描述包的功能

✅ 好的包名:data_analysis, web_scraper
❌ 不好的包名:MyPackage, data-analysis

3. 文档和测试

# mypackage/__init__.py
"""
MyPackage - 数据处理工具包提供一系列数据处理、分析和可视化的工具。功能:
- 数据清洗
- 统计分析
- 报告生成示例:
>>> from mypackage import DataProcessor
>>> processor = DataProcessor()
>>> result = processor.analyze(data)
"""__version__ = "1.0.0"

4. 版本控制

  • 使用语义化版本(Semantic Versioning)
  • MAJOR.MINOR.PATCH 格式
  • 重大变更时更新 MAJOR 版本

总结

本文主要对模块以及包的详细学习和探讨,有助于后续学习更深一层的python各种算法库打下好的基础。一起努力成长!!

资料关注

相关资料获取:
公众号:咚咚王

艺术二维码.png

《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen) 》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》

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

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

相关文章

基于Playwright + Allure + Pytest 企业级UI录制与回放自动化测试项目

基于Playwright + Allure + Pytest 企业级UI录制与回放自动化测试项目录制脚本: UI回放开始: 生成测试报告:

IM SDK选型避坑指南,2025年最新10家服务商稳定性排名

IM SDK选型避坑指南,2025年最新10家服务商稳定性排名随着移动互联网的深入发展,即时通讯已渗透到各行各业,从日常的社交聊天到关键业务的金融交易、远程医疗、在线教育,稳定可靠的IM服务成为保障用户体验和业务连续…

自定义yml激活进本地通用yml

自定义yml激活进本地通用yml 核心结论:自定义 YML 可通过「继承引用」「合并配置」或「指定加载顺序」三种方式,激活并复用本地通用 YML 的配置。 关键实现方式Spring Boot 场景(最常用):通用 YML 作为 base 配置…

AT_jsc2019_qual_e Card Collector

首先考虑什么情况不合法。假设 \(S\) 为选出卡片的集合,玩一下发现不合法当且仅当存在 \(T\subseteq S\),\(X=\{x|(x,y)\in T\}\),\(Y=\{y|(x,y)\in T\}\) 满足 \(|X|+|Y|<|T|\)。 假设当前需要加入一个点 \((x_…

人工智能之编程基础 Python 入门:第八章 函数与装饰器

人工智能之编程基础 Python 入门:第八章 函数与装饰器人工智能之编程基础 Python 入门 第八章 函数与装饰器@目录人工智能之编程基础 Python 入门前言函数1. 函数的定义与调用基本语法简单示例2. 函数的组成部分3. 参…

邻项交换

又称微扰法等 例题 最小化最大延迟惩罚 有 n 个任务,每个任务有一个有用时 \(p_i\) 和一个截止时间 \(d_i\),若完成时间为 \(c_i\),要最小化 \(max{c_i - d_i}\)。 考虑如果有两个相邻的 \(i\) 和 \(j\),不交换答案…

day26-MCP基础

MCP快速入门实战 一、MCP技术体系介绍 MCP,全称是Model Context Protocol,模型上下文协议,由Claude母公司Anthropic于2024年11月正式提出。MCP解决的最大痛点,就是Agent开发中调用外部工具的技术门槛过高的问题。 …

20232427 2025-2026-1 《网络与系统攻防技术》实验六实验报告

一、实验内容 本次实验聚焦 Metasploit 攻击渗透实践,核心内容包括两部分:一是前期渗透准备,通过主机发现、端口扫描及漏洞扫描获取靶机基础信息;二是漏洞渗透利用,针对 Metasploitable2 靶机的 4 类典型漏洞(Vs…

P9534 [YsOI2023] 广度优先遍历

考虑一个事情,把树建出来后,非树边都可以扔到后面去,这显然不影响答案。 思考为什么树边的顺序会影响答案,实质是因为一个结点 \(x\) 连了许多非树边,若是这些非树边先被访问了,那么 \(x\) 的父亲就要换了,因此…

2025-11-17 ZYZ28-NOIP模拟赛-Round7 hetao1733837的record

2025-11-17 ZYZ28-NOIP模拟赛-Round7 hetao1733837的record2025-11-17 ZYZ28-NOIP模拟赛-Round7 hetao1733837的record 好累😩 比赛链接:ZYZ28-NOIP模拟赛-Round7 - ZYZOJ A.pmst $( ‵▽′)ψ$$lz$竟然把原来的$T2…

day25-langgraph进阶

整体课程设计介绍 第一次直播:开班介绍+环境适配+自主学习任务布置 任务:预习系列(参考2期)day20-大模型基本概述+API调用 day21-大模型基本概述+API调用 day22-langchain框架基础 day23-langchain框架进阶第二次直…

markdown格式绘制各种图

推荐使用 Mermaid 进行绘制

11.17 考试总结

11.17 考试总结 赛时复盘 7:50-8:10 通读了题面,有了点第一印象,T1感觉像是贪心,T2没什么头绪,T3是计数题看数据范围感觉像是个简单DP,T4感觉很困难,决定了开题顺序:1-3-2-4。 8:10-9:10 根据特殊性质先想树上发…

计算机网络第六章---应用层(基于谢希仁老师第八版)

​ 6.1域名系统DNS(Domain Name System) 作用:把主机名字转化为IP地址 理论上整个互联网可以只使用一个域名服务器,但是规模太大不可取,所以采用了层次树状结构的命名方法,并使用分布式的域名系统DNS===>采用…

第一次接触 JSAPIThree(百度地图 JSAPI Three)学习笔记

这是一篇关于百度地图 JSAPI Three(mapvthree)的入门学习笔记,以初学者的视角记录从安装配置到第一个 Hello World 的完整学习过程,包含详细的步骤说明和实践经验。作为一个前端小白,今天要开始学习百度地图的 JS…

Who wants to be king:2

前言写这篇文章的本意,是为了记录关于vulnhub上的靶机who wants to be king2的练习过程,同时向社区大佬请教一个问题,希望各位大佬可以指点一下。问题如下:这个靶机提权部分按照靶机作者的思路,是要到.mozilla文件…