Python模块化开发三部曲:模块/包/导入详解与第三方依赖管理实战

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

目录

一、模块Module

1 模块详解

2 模块的导入

3 模块的分类

3.1 系统模块

3.2 第三方模块

3.3 自定义模块

3.4 模块搜索路径

二、包

1 包的详解

2 包的导入

2.1 绝对导入(推荐!!)

2.2 导入整个子包

3 包的设计

三、模块与包的区别

 今日份注意!!!


一、模块Module

1 模块详解

1.1 什么是模块化?

  • 将代码划分为独立的、可复用的功能单元

  • 类比:乐高积木(每个模块是独立积木,组合成完整系统)

  • 时Python程序的最小可复用单元

1.2 为什么需要模块化?

  • ✅ 避免重复代码

  • ✅ 便于协作开发

  • ✅ 提高可维护性

  • ✅ 实现命名空间隔离

1.3 模块的本质:

  • 任何.py文件都是一个模块

1.4 模块的组成:

  • 变量
  • 函数
  • 可执行代码

2 模块的导入

2.1 导入模块

  • 语法:

1)import 模块名 [as 模块新名字]   # 导入一个模块到当前程序

2)from 模块名 import 模块属性名 [as 属性新名字]   # 导入一个模块内部的部分属性到当前程序,多个属性名由逗号隔开

3)from 模块名 import *  # 导入一个模块内部的全部属性到当前程序

  • 示例:
# 1)import 模块名 [as 模块新名字]  # 导入一个模块到当前程序
import math
print(math.sqrt(16))  # 4
# 2)from 模块名 import 模块属性名 [as 属性新名字]  # 导入一个模块内部的部分属性到当前程序,多个属性名由逗号隔开
from math import pi
print(pi)  # 3.141592653589793
# 3)from 模块名 import *  # 导入一个模块内部的全部属性到当前程序
from math import *
print(sqrt(16))  # 4
print(pi)  # 3.141592653589793

2.2 内部属性

  • __file__  绑定模块的路径
  • __name__属性

每个模块都有一个__name__属性,当模块作为主程序运行时,其__name__属性的值为'__main__';而当模块被其他模块导入时,__name__属性的值就是模块的名称。

3 模块的分类

3.1 系统模块

这类模块是 Python 标准库的一部分,用户无需额外安装就能直接使用。

特点:

  • 由 Python 标准库自带,无需额外安装
  • 覆盖基础功能(数学计算、文件操作、系统接口等)
  • 开箱即用,是 Python 生态的核心组成部分

常见内置模块:

模块名称主要功能示例代码
math数学函数(平方根、三角函数等)import math; math.sqrt(16)
random随机数生成import random; random.randint(1,10)
os操作系统接口(文件路径、环境变量)import os; os.getcwd()
sysPython 解释器相关(命令行参数、路径)import sys; sys.version
datetime日期和时间处理from datetime import datetime; datetime.now()

使用方式:

import datetime

if __name__ == '__main__':
    # 获取当前时间
    time_new = datetime.datetime.now()
    print(time_new)

    # 一指定的格式进行输出:2025年04月02日 10:23:32
    time_new2 = time_new.strftime('%Y年%m月%d日 %H:%M:%S')
    print(time_new2)
import os

# 获取计算机名
computer_name = os.environ.get('COMPUTERNAME')
print(computer_name)

# 用于在 Windows 系统下暂停程序执行并显示提示信息的命令
# os.system('pause')

print(computer_name)

# 获取当前文件所在的目录
file = os.path.dirname(__file__)
# 获取上一层的目录
print(os.path.dirname(file))
# 创建目录
# os.makedirs()

# 文件路径拼接
filepath = os.path.join(os.path.dirname(file), 'day9', 'xml_two')
print(filepath)

# 判断文件是否存在
print(os.path.exists(filepath))
import random

if __name__ == '__main__':
    # 生成 n 位的数字密码
    def generate_password(n):
        password = ''
        for i in range(n):
            password += str(random.randint(0, 9))  # 随机生成0~9数字
        return password

    n = 6  # 密码位数
    pw = generate_password(n)
    print('密码:', pw)

    characters = '0123456789abcdefghijklmnopqrstwuxyz'

# 生成 n 位的数字和字母组成的密码
    def generate_password2(x):
        password2 = ''
        for i in range(x):
            password2 += random.choice(characters)  # random.choice()随机选择一个元素
        return password2

    x = 9
    pw2 = generate_password2(x)
    print('密码:', pw2)

3.2 第三方模块

这是由 Python 社区开发的模块,用户需要先安装才能使用,安装时通常会借助包管理工具,如pip。

特点:

  • 由 Python 社区或第三方开发者创建
  • 需通过包管理器(如pip)安装
  • 功能覆盖范围广(Web 开发、数据科学、机器学习等)

安装第三方模块:

# 使用pip安装(最常用方式)
pip install requests

# 指定版本安装
pip install pandas==1.5.3

# 从requirements.txt批量安装(从其他地方导出的依赖)
pip install -r requirements.txt

导出所有依赖包到requirments.txt:

pip freeze > requirements.txt

卸载第三方模块:

# 卸载单个模块
pip uninstall 模块名

# 强制卸载(忽略依赖冲突)
pip uninstall 模块名 --yes

# 示例:卸载requests
pip uninstall requests

导入与使用:(下载图片)

import requests
import json
import os

category = {
    'cat': '猫',
    'dog': '狗',
    'plane': '飞机',
    'bird': '鸟',
}

# 当前文件所在目录
CURRENT_DIR = os.path.dirname(__file__)
# 页数
PAGES_NUM = 10

if __name__ == '__main__':
    for key, value in category.items():
        # 下载图片到本地目录(当前文件目录 + 字典关键字)
        folder = os.path.join(CURRENT_DIR, key)
        # 判断一下是否有文件目录,没有就创建
        if not os.path.exists(folder):
            os.makedirs(folder)

        # 遍历的方式爬取多页
        for page in range(PAGES_NUM):
            # 访问网站(一页下载30张,总共下载30 * page)
            url = f"https://image.baidu.com/search/acjson?tn=resultjson_com&word={value}&ie=utf-8&fp=result&fr=&ala=0&applid=12093134800464237813&pn={30 * page}&rn=30&nojc=0&gsm=12c&newReq=1"
            # 设置请求头:模拟浏览器
            headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
            }
            # 使用requests模块发送请求:第三方模块和系统模块的使用
            response = requests.get(url, headers=headers)
            # json.loads() 将JSON字符串转换为Python字典(dict)
            # response.text 获取响应内容(自定解码为字符串)
            images = json.loads(response.text).get('data').get('images')

            # 获取到所有我要加载到本地的图片地址,因为images是字典,所以需要遍历字典
            image_urls = [image.get('thumbURL') for image in images]

            # 将每张图片存储到我们指定的路径
            for i, image_url in enumerate(image_urls):
                # 通过 HTTP GET 请求下载指定 URL 的图片数据
                image_data = requests.get(image_url)
                with open(os.path.join(folder,f'{key}_{(page * 30 + i) + 1}.jpg'),mode='wb') as f:
                    f.write(image_data.content)
                    print(f'{value}第{(page * 30 + i) + 1}张图片下载成功')

常见第三方模块分类:

领域代表模块主要用途
Web 开发Flask/Django构建 Web 应用
数据科学NumPy/Pandas/Matplotlib数值计算、数据分析、可视化
机器学习Scikit-learn/TensorFlow模型训练、深度学习
自动化测试pytest/Unittest单元测试、集成测试
爬虫Scrapy/BeautifulSoup网页数据抓取与解析
异步编程Asyncio/FastAPI高性能异步服务开发

3.3 自定义模块

用户可以自己创建模块,把相关的代码放在同一个.py文件中,然后在其他文件里导入使用。

特点:

  • 由开发者自己创建的模块或包
  • 用于组织项目内的代码结构
  • 支持跨文件复用功能

创建模块文件:

def add(a):
    sum = 1
    for i in range(1,a+1):
        sum *= i
    return sum


def sub(a, b):
    if a < b:
        return b-a
    else:
        return a-b

在其他文件导入使用:

import modulefile

de1 = modulefile.add(5)
print(de1)  # 120
de2 = modulefile.sub(6, 2)
print(de2)  # 4

3.4 模块搜索路径

当导入一个模块时,Python会按照以下顺序查找该模块:

  1. 首先查找当前目录。
  2. 接着查找环境变量PYTHONPATH中指定的目录。
  3. 最后查找 Python 安装时默认的库目录。

用户可通过sys.path来了解模块的搜索路径:

import sys
print(sys.path)  # 打印模块搜索路径列表

二、包

1 包的详解

什么是包?

  • 包含 __init__.py 文件的特殊目录

  • 作用:将相关模块组织为层次化命名空间

  • 类比:

    • 模块 → 单个文件(如 utils.py

    • 包 → 文件夹 + 多个模块(如 my_package/

包的价值

  • ✅ 解决命名冲突

  • ✅ 实现功能模块化拆分

  • ✅ 支持大型项目代码复用

包的基础结构

my_package/          # 包目录
├── __init__.py      # 包声明文件(可空)
├── module1.py       # 模块1
├── module2.py       # 模块2
└── subpackage/      # 子包
    ├── __init__.py  # 子包声明
    └── submodule.py # 子包内模块

__init__.py 文件详解

1、声明包:空的__init__.py文件即可声明目录为 Python 包。

2、限制导入范围:通过__all__变量控制from package import *的行为

3、执行初始化代码: 可以包含任何代码,通常用于包的初始化操作,如变量初始化、导入模块等。这些代码在包被导入时执行。

4、提供包级别的命名空间: __init__.py 中定义的变量和函数可以在包的模块中共享。

5、批量导入模块: 可以在 __init__.py 文件中批量导入模块,这些模块可以更方便地使用。

# 1. 批量导入系统模块
import os
import sys
import datetime

# 2. 定义包级别的变量
package_variable = "This is a package variable"

# 3. 控制包的导入行为
__all__ = ['module1', 'module2']

# 4. 执行初始化代码
print("Initializing mypackage")

# 注意:这个代码会在包被导入时执行

# 5. 导入包内的模块
from . import module1
from . import module2

包资源:

在包中包含非Python文件(如配置、模板)

my_package/
├── data/
│   └── config.json
└── utils.py

通过importlib.resource访问:

# utils.py
from importlib import resources

def read_config():
    with resources.open_text('my_package.data', 'config.json') as f:
        return f.read()

2 包的导入

2.1 绝对导入(推荐!!)

通过完整路径导入模块或子包

# 同模块的导入规则
import 包名 [as 包别名]
import  包名.模块名 [as 模块新名]
import  包名.子包名.模块名 [as 模块新名]
    
from 包名 import 模块名 [as 模块新名]
from 包名.子包名 import 模块名 [as 模块新名]
from 包名.子包名.模块名 import 属性名 [as 属性新名]

from 包名.模块名 import *
from touch import nn
from touch.nn import ConvNet3
from touch.nn import *

nn.ConvNet()
nn.ConvNet2()
ConvNet3()

2.2 导入整个子包

在包的__init__.py中明确指定要导出的子包和模块,然后通过from 包名 import *导入:

# 导入包内的所有子包和模块
from 包名 import *
# __init__.py 中的代码
from .nn import ConvNet, ConvNet2, ConvNet3

__all__ = ['ConvNet3',
           'ConvNet2',
           'ConvNet']
# 主程序的代码
from touch import *

ConvNet3()

3 包的设计

目录结构设计:

  • 按功能划分模块和子包(如web/db/utils/)。
  • 避免过深的嵌套层级(建议不超过 3 层)。

__init__.py 优化:

  • 保持__init__.py简洁,仅导入常用功能。
  • 避免在__init__.py中执行耗时操作(影响导入性能)。

文档与测试:

  • 为包和子包添加README.md说明用途。
  • 在包内创建tests/目录存放单元测试。

避免循环导入:

  • 若模块A和B相互依赖,将共享代码提取到第三方模块C。

三、模块与包的区别

区别:

  • 模块是 Python 代码的基本单元(单个文件),而是模块的集合(目录结构)。
  • 包通过__init__.py声明,并支持多层级组织,适合大型项目的模块化管理。
  • 合理使用模块和包能提升代码的可维护性、复用性和可读性。

模块与包的选择原则:

  • 小型项目 / 功能单一:直接使用模块。
  • 大型项目 / 多模块协作:使用包组织,通过子包划分功能域。
  • 避免命名冲突:包提供多层级命名空间(如package.module1 vs package.module2)。
  • 代码复用:将常用功能封装为独立模块或包,便于跨项目复用。

核心区别:

特性

模块(Module)包(Package)
物理形式单个.py文件目录 + __init__.py(可选) + 多个模块
导入方式import module_nameimport package.module 或 from package import module
代码规模小型功能单元大型项目的模块化组织
命名空间模块名作为命名空间(如module.func包名 + 模块名作为命名空间(如package.module.func
嵌套层级无(单文件)支持多级子包(如package.subpackage.module
典型应用场景工具函数、小型库框架(如 Django、Flask)、大型项目

 今日份注意!!!

不同模块中的同名函数/类会互相覆盖,为避免覆盖可使用别名

不要循环导入,比如说:模块 A 导入模块 B,同时模块 B 导入模块 A,导致运行时错误。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值