28. Python标准库概览

一、标准库简介

标准库的定义

Python 标准库(Standard Library)是 Python 语言自带的一组模块和包,提供了丰富的功能,涵盖了文件操作、网络通信、数据处理、系统交互等常见任务。这些模块和包无需额外安装,可以直接导入使用。

标准库的作用

  1. 提供基础功能:如文件操作(ossys)、数学计算(math)、日期时间处理(datetime)等。
  2. 简化开发:封装常用功能,避免重复造轮子,提高开发效率。
  3. 跨平台兼容:标准库的模块通常已处理好不同操作系统的兼容性问题。

使用场景

  1. 文件操作:使用 osshutil 模块管理文件和目录。
  2. 数据处理:使用 jsoncsv 模块解析和生成数据文件。
  3. 网络请求:通过 urllibhttp.client 发送 HTTP 请求。
  4. 多线程/多进程:利用 threadingmultiprocessing 实现并发。

注意事项

  1. 避免重复造轮子:优先使用标准库,而非自己实现已有功能。
  2. 版本差异:部分模块在不同 Python 版本中可能有行为差异(如 urllib 在 Python 2 和 3 中的拆分)。
  3. 性能问题:某些模块(如 xml.etree.ElementTree)可能不如第三方库(如 lxml)高效。

示例代码

import os
from datetime import datetime

# 文件操作:列出当前目录内容
print(os.listdir('.'))

# 日期处理:获取当前时间并格式化
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

输出示例:

['main.py', 'data.txt']
2023-10-20 14:30:00

内置模块与包的结构

概念定义

内置模块是Python解释器自带的模块,无需额外安装即可使用。包是一种特殊的模块,包含多个模块或子包,通常以目录形式存在,并包含__init__.py文件。

使用场景
  1. 内置模块:直接使用Python提供的功能(如ossysmath等)。
  2. :组织大型项目代码,实现模块化开发。
常见误区
  1. 命名冲突:自定义模块/包名与内置模块同名时,会优先加载自定义模块。
  2. __init__.py:Python 3.3+中可省略,但显式声明包结构更规范。
  3. 路径问题:包内模块相互引用时需使用相对或绝对路径(如from . import module)。
示例代码
  1. 内置模块调用
import math
print(math.sqrt(16))  # 输出: 4.0
  1. 包结构示例
my_package/
    __init__.py
    module1.py
    subpackage/
        __init__.py
        module2.py
  1. 包内模块引用
# my_package/module1.py
from .subpackage import module2

标准库的版本兼容性

概念定义

Python标准库版本兼容性指的是在不同Python版本中,标准库模块和功能的可用性和行为一致性。随着Python版本更新,部分标准库模块可能被弃用(deprecated)、移除(removed)或修改行为。

使用场景
  1. 项目需要支持多个Python版本时
  2. 维护遗留代码时
  3. 在不同环境中部署应用时
  4. 使用较新的标准库功能时需要考虑向后兼容
常见误区或注意事项
  1. 假设所有标准库在所有Python版本中都可用(如pathlib在Python 3.4+才成为标准库)
  2. 忽略弃用警告(deprecation warnings),可能导致未来版本不兼容
  3. 未测试代码在不同Python版本下的行为
  4. 混淆标准库和第三方库的版本要求
示例代码
import sys

# 检查Python版本
if sys.version_info < (3, 7):
    # 使用兼容方案
    from collections import OrderedDict
    my_dict = OrderedDict()
else:
    # Python 3.7+ 字典已保持插入顺序
    my_dict = {}

# 检查模块可用性
try:
    import statistics
    avg = statistics.mean([1, 2, 3])
except ImportError:
    # 回退方案
    avg = sum([1, 2, 3]) / 3
版本特性检查
# 检查特定功能是否可用
if hasattr(os, 'scandir'):  # Python 3.5+
    for entry in os.scandir('.'):
        print(entry.name)
else:
    for name in os.listdir('.'):
        print(name)

二、常用模块分类

os 模块

概念定义

os 模块提供了与操作系统交互的函数,用于执行文件和目录操作、进程管理等系统级任务。

使用场景
  1. 文件和目录操作(创建、删除、重命名)
  2. 获取系统信息(环境变量、当前工作目录)
  3. 执行系统命令
  4. 进程管理
常见误区
  1. 路径分隔符在不同系统中不同(Windows用\,Linux用/),建议使用os.path.join()处理路径
  2. 文件操作前应先检查文件是否存在(os.path.exists()
示例代码
import os

# 获取当前工作目录
current_dir = os.getcwd()

# 创建目录
os.makedirs("new_folder")

# 列出目录内容
files = os.listdir(".")

# 跨平台路径拼接
file_path = os.path.join("folder", "file.txt")

sys 模块

概念定义

sys 模块提供对Python解释器相关功能的访问,包括命令行参数、标准输入输出、解释器版本等。

使用场景
  1. 获取命令行参数
  2. 修改Python运行时环境
  3. 处理标准输入/输出/错误流
  4. 获取Python解释器信息
常见误区
  1. sys.argv[0]是脚本名,实际参数从sys.argv[1]开始
  2. 修改sys.path会影响模块搜索路径,可能导致导入问题
示例代码
import sys

# 获取命令行参数
script_name = sys.argv[0]
arguments = sys.argv[1:]

# 获取Python版本
version = sys.version

# 修改标准输出
sys.stdout.write("自定义输出\n")

# 退出程序
sys.exit(1)  # 非零表示异常退出
两个模块的主要区别
  1. os:主要与操作系统交互(文件、进程等)
  2. sys:主要与Python解释器交互(运行时环境、参数等)

文件处理(pathlib, shutil)

概念定义

Python 提供了 pathlibshutil 模块来处理文件和目录操作:

  • pathlib:面向对象的文件系统路径操作库,提供更直观的路径操作方法。
  • shutil:高级文件操作库,用于复制、移动、删除文件和目录。
使用场景
  • pathlib:适用于路径拼接、检查文件/目录是否存在、创建目录等。
  • shutil:适用于文件/目录的复制、移动、删除等操作。
常见误区或注意事项
  1. 跨平台兼容性pathlib 会自动处理不同操作系统的路径分隔符(/\)。
  2. 文件权限:使用 shutil 操作文件时需确保有足够的权限。
  3. 路径检查:操作前建议用 exists() 检查路径是否存在。
示例代码
from pathlib import Path
import shutil

# 使用 pathlib 创建目录和文件
path = Path("example_dir")
path.mkdir(exist_ok=True)  # 创建目录(如果不存在)
file_path = path / "test.txt"  # 路径拼接
file_path.write_text("Hello, World!")  # 写入文件

# 检查文件是否存在
if file_path.exists():
    print(f"File size: {file_path.stat().st_size} bytes")

# 使用 shutil 复制文件
shutil.copy(file_path, path / "test_copy.txt")

# 删除目录(包括内容)
shutil.rmtree(path)

日期时间处理

Python提供了datetimetime模块来处理日期和时间相关的操作。

datetime模块

datetime模块包含的主要类:

  • datetime.date:处理日期(年、月、日)
  • datetime.time:处理时间(时、分、秒、微秒)
  • datetime.datetime:处理日期和时间
  • datetime.timedelta:处理时间间隔
基本用法
from datetime import datetime, date, time, timedelta

# 获取当前日期和时间
now = datetime.now()
print(now)  # 2023-03-15 14:30:45.123456

# 创建特定日期
d = date(2023, 3, 15)
print(d)  # 2023-03-15

# 创建特定时间
t = time(14, 30, 45)
print(t)  # 14:30:45

# 时间运算
tomorrow = now + timedelta(days=1)
print(tomorrow)  # 2023-03-16 14:30:45.123456
time模块

time模块提供了时间相关的函数,主要用于时间戳和格式化。

常用功能
import time

# 获取时间戳
timestamp = time.time()
print(timestamp)  # 1678887045.123456

# 格式化时间
local_time = time.localtime()
print(time.strftime("%Y-%m-%d %H:%M:%S", local_time))  # 2023-03-15 14:30:45

# 暂停执行
time.sleep(2)  # 暂停2秒
使用场景
  1. 记录日志时间戳
  2. 计算任务执行时间
  3. 处理用户输入的日期
  4. 定时任务调度
  5. 数据分析和处理中的时间序列
注意事项
  1. 时区处理:Python默认使用本地时区,跨时区应用需要考虑时区转换
  2. 性能:频繁的时间操作可能影响性能
  3. 格式化字符串要正确:如%Y是四位年份,%y是两位年份
  4. 时间戳精度:不同系统可能有不同的精度
常见误区
  1. 混淆datetimetime模块的功能
  2. 忘记处理时区问题
  3. 使用错误的格式化字符串
  4. 认为time.time()返回的是可读时间(实际是时间戳)
格式化示例
from datetime import datetime

# 正确格式化
dt = datetime.now()
print(dt.strftime("%A, %B %d, %Y"))  # Wednesday, March 15, 2023

# 错误示例(容易混淆的格式)
# print(dt.strftime("%D"))  # 03/15/23 (可能不是预期格式)

数据压缩与归档

Python提供了zipfiletarfile模块来处理常见的压缩和归档文件格式。

zipfile模块

zipfile模块用于处理ZIP格式的压缩文件。

创建ZIP文件
import zipfile

with zipfile.ZipFile('example.zip', 'w') as zipf:
    zipf.write('file1.txt')  # 添加单个文件
    zipf.write('file2.txt')
读取ZIP文件
with zipfile.ZipFile('example.zip', 'r') as zipf:
    zipf.extractall('extracted_files')  # 解压所有文件
    # 或者单独解压某个文件
    zipf.extract('file1.txt', 'specific_dir')
注意事项
  1. 默认不会压缩空目录
  2. 写入模式(‘w’)会覆盖现有文件
  3. 使用compresslevel参数可以控制压缩级别
tarfile模块

tarfile模块用于处理tar归档文件,支持gzip、bz2等压缩格式。

创建tar文件
import tarfile

# 创建gzip压缩的tar文件
with tarfile.open('example.tar.gz', 'w:gz') as tar:
    tar.add('folder_to_compress')  # 添加整个目录
读取tar文件
with tarfile.open('example.tar.gz', 'r:gz') as tar:
    tar.extractall('extracted_folder')  # 解压全部
    # 或者获取文件列表
    print(tar.getnames())
常见模式
  • ‘w’ 或 ‘w:’ - 未压缩的tar
  • ‘w:gz’ - gzip压缩
  • ‘w:bz2’ - bzip2压缩
  • ‘w:xz’ - xz压缩
使用场景
  1. 批量文件传输前压缩
  2. 日志文件归档
  3. 备份重要数据
  4. 减少存储空间占用
常见误区
  1. 忘记关闭文件可能导致数据损坏
  2. 路径处理不当可能导致文件被解压到错误位置
  3. 大文件处理时内存消耗问题
  4. 不同操作系统路径分隔符差异

网络通信(socket, urllib)

概念定义

网络通信是指计算机之间通过网络进行数据交换的过程。在Python中,常用的网络通信模块包括:

  • socket:提供低级别的网络通信接口,支持TCP/UDP协议
  • urllib:提供高级别的HTTP客户端功能,简化了HTTP请求操作
使用场景
  1. socket适用于:

    • 需要直接控制网络协议细节的情况
    • 开发自定义协议或非HTTP协议的应用
    • 需要高性能网络通信的场景
  2. urllib适用于:

    • 快速实现HTTP/HTTPS请求
    • 不需要底层控制的标准Web请求
    • 简单的网页抓取或API调用
常见误区或注意事项
  1. socket

    • 忘记关闭连接会导致资源泄漏
    • 需要手动处理字节编码/解码
    • 缓冲区大小设置不当可能导致数据丢失
  2. urllib

    • 默认不验证HTTPS证书,存在安全风险
    • 缺乏连接池管理,频繁请求效率低
    • 错误处理机制相对简单
示例代码
  1. socket示例(TCP客户端):
import socket

# 创建TCP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('example.com', 80))

# 发送HTTP请求
request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
client_socket.sendall(request)

# 接收响应
response = client_socket.recv(4096)
print(response.decode())

client_socket.close()
  1. urllib示例:
from urllib.request import urlopen

# 发起GET请求
with urlopen('https://example.com') as response:
    content = response.read().decode('utf-8')
    print(content)

三、高级功能模块

并发执行

概念定义

并发执行是指在同一时间段内,多个任务交替执行的能力。在Python中,主要通过multiprocessing(多进程)和threading(多线程)模块实现。

使用场景
  1. CPU密集型任务:推荐使用multiprocessing,因为可以绕过GIL(全局解释器锁),充分利用多核CPU。
  2. I/O密集型任务:推荐使用threading,因为线程切换开销小,适合等待I/O操作(如网络请求、文件读写)的场景。
常见误区
  1. 线程安全:多线程共享内存,需注意数据竞争问题(如使用Lock)。
  2. GIL限制:多线程因GIL无法真正并行执行CPU密集型任务。
  3. 进程开销:多进程内存独立,创建和通信开销较大。
示例代码
多线程(I/O密集型)
import threading

def download(url):
    print(f"Downloading {url}...")
    # 模拟I/O操作
    import time
    time.sleep(2)
    print(f"Finished {url}")

urls = ["url1", "url2", "url3"]
threads = []
for url in urls:
    t = threading.Thread(target=download, args=(url,))
    t.start()
    threads.append(t)

for t in threads:
    t.join()
多进程(CPU密集型)
import multiprocessing

def calculate(n):
    return n * n

if __name__ == "__main__":
    with multiprocessing.Pool() as pool:
        results = pool.map(calculate, [1, 2, 3])
    print(results)  # 输出: [1, 4, 9]

数据持久化

数据持久化是指将程序运行中的数据保存到存储介质(如硬盘)中,以便程序下次运行时可以重新加载使用。Python中常用的数据持久化工具有picklesqlite3

pickle模块

pickle是Python内置的序列化模块,可以将Python对象转换为字节流(序列化),也可以将字节流还原为Python对象(反序列化)。

使用场景
  • 保存机器学习模型
  • 存储程序配置
  • 缓存计算结果
注意事项
  1. 不要反序列化不受信任的数据,可能存在安全风险
  2. 不同Python版本间的pickle文件可能不兼容
  3. 对于大型数据集,pickle可能不是最佳选择
示例代码
import pickle

# 序列化
data = {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)

# 反序列化
with open('data.pkl', 'rb') as f:
    loaded_data = pickle.load(f)
print(loaded_data)  # {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
sqlite3模块

sqlite3是Python内置的轻量级数据库模块,使用SQLite数据库实现数据持久化。

使用场景
  • 需要结构化存储数据
  • 需要进行复杂查询
  • 需要事务支持
注意事项
  1. SQLite是文件型数据库,不适合高并发场景
  2. 所有表都存储在单个数据库文件中
  3. 数据类型较为简单(NULL, INTEGER, REAL, TEXT, BLOB)
示例代码
import sqlite3

# 创建数据库连接
conn = sqlite3.connect('example.db')
cursor = conn.cursor()

# 创建表
cursor.execute('''CREATE TABLE IF NOT EXISTS users
                  (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')

# 插入数据
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 25))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 30))

# 查询数据
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())  # [(1, 'Alice', 25), (2, 'Bob', 30)]

# 提交并关闭
conn.commit()
conn.close()
选择建议
  • 需要简单存储Python对象 → 使用pickle
  • 需要结构化存储和查询 → 使用sqlite3
  • 需要处理大型数据集 → 考虑专业数据库系统(如MySQL、PostgreSQL等)

JSON 数据格式处理

概念定义

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,采用文本格式存储和传输数据,易于人阅读和编写,也易于机器解析和生成。

使用场景
  1. Web API 数据传输
  2. 配置文件存储
  3. 不同语言间的数据交换
常见操作
import json

# 将Python对象转为JSON字符串
data = {"name": "Alice", "age": 25}
json_str = json.dumps(data)

# 将JSON字符串转为Python对象
python_obj = json.loads(json_str)

# 读写JSON文件
with open('data.json', 'w') as f:
    json.dump(data, f)

with open('data.json') as f:
    loaded_data = json.load(f)
注意事项
  1. JSON 键名必须用双引号
  2. 不支持 Python 特有数据类型(如 datetime)
  3. 默认编码为 UTF-8

CSV 数据格式处理

概念定义

CSV (Comma-Separated Values) 是以纯文本形式存储表格数据的文件格式,用逗号分隔字段。

使用场景
  1. 电子表格数据导出/导入
  2. 简单结构化数据存储
  3. 数据分析预处理
常见操作
import csv

# 写入CSV文件
with open('data.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['Name', 'Age'])
    writer.writerow(['Alice', 25])
    writer.writerow(['Bob', 30])

# 读取CSV文件
with open('data.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

# 字典方式读写
with open('data.csv', 'w', newline='') as f:
    fieldnames = ['name', 'age']
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'name': 'Alice', 'age': 25})
注意事项
  1. 注意处理包含逗号的数据(应使用引号包裹)
  2. 不同系统换行符可能不同(建议使用 newline=''
  3. 大文件处理时应逐行读写而非全部加载

测试框架

Python内置了两个主要的测试框架:unittestdoctest,用于帮助开发者编写和运行测试用例。

unittest框架
概念定义

unittest是一个基于xUnit架构的测试框架,提供了测试用例、测试套件、测试夹具等概念。

使用场景
  • 需要结构化测试代码时
  • 需要测试复杂逻辑时
  • 需要测试类和方法时
  • 需要测试前后执行固定代码时(setUp/tearDown)
常见误区
  1. 忘记继承unittest.TestCase
  2. 测试方法不以test_开头
  3. 混淆assertEqualassertTrue的使用场景
示例代码
import unittest

class TestStringMethods(unittest.TestCase):
    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

if __name__ == '__main__':
    unittest.main()
doctest框架
概念定义

doctest是一个通过解析文档字符串中的示例来验证代码行为的轻量级测试框架。

使用场景
  • 函数/方法有简单明确的输入输出时
  • 需要将文档和测试结合时
  • 快速验证示例代码时
注意事项
  1. 示例必须精确匹配实际输出
  2. 复杂的测试逻辑不适合用doctest
  3. 测试失败时难以定位问题
示例代码
def factorial(n):
    """计算阶乘
    
    >>> factorial(3)
    6
    >>> factorial(5)
    120
    """
    return 1 if n <= 1 else n * factorial(n-1)

if __name__ == "__main__":
    import doctest
    doctest.testmod()
框架选择建议
  • 选择unittest当需要:复杂测试逻辑、测试夹具、测试组织
  • 选择doctest当需要:简单示例验证、文档驱动测试

调试工具(pdb, trace)

Python提供了内置的调试工具,帮助开发者查找和修复代码中的错误。最常用的调试工具是pdb模块和trace模块。

pdb模块

pdb是Python的标准调试器,允许你设置断点、单步执行代码、检查变量值等。

使用场景
  • 当代码出现逻辑错误但难以定位时
  • 需要检查程序执行过程中变量的变化
  • 理解复杂代码的执行流程
常见用法
  1. 在代码中插入断点:
import pdb

def calculate(x, y):
    pdb.set_trace()  # 设置断点
    result = x + y
    return result

calculate(3, 5)
  1. 常用命令:
  • n(next): 执行下一行
  • s(step): 进入函数调用
  • c(continue): 继续执行直到下一个断点
  • l(list): 显示当前代码
  • p(print): 打印变量值
  • q(quit): 退出调试器
注意事项
  • 调试完成后记得删除set_trace()调用
  • 在生产环境中不要保留调试代码
  • 对于复杂程序,建议使用IDE的图形化调试工具
trace模块

trace模块用于跟踪程序执行,生成执行报告。

使用场景
  • 分析代码覆盖率
  • 理解程序执行路径
  • 查找未执行的代码
示例代码
import trace
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], trace=0, count=1)
tracer.run('import mymodule')  # 跟踪mymodule的执行
常用参数
  • count=1: 统计每行代码的执行次数
  • trace=1: 显示执行的行
  • ignoredirs: 忽略特定目录
注意事项
  • 跟踪会显著降低程序执行速度
  • 生成的报告可能很大,需要过滤分析
  • 主要用于测试阶段,而非生产环境

四、标准库使用技巧

模块导入最佳实践

概念定义

模块导入是指将其他Python文件或内置模块中的代码引入当前程序的过程。良好的导入实践可以提高代码的可读性、可维护性和性能。

使用场景
  1. 需要复用其他模块中的函数、类或变量时
  2. 项目结构复杂需要分模块组织代码时
  3. 需要使用Python标准库或第三方库时
最佳实践
  1. 标准库导入优先
import os
import sys
  1. 第三方库导入次之
import numpy as np
import pandas as pd
  1. 本地模块导入最后
from . import utils
from models import User
  1. 推荐使用绝对导入
from package.subpackage import module
  1. 避免使用通配符导入
# 不推荐
from module import *
  1. 合理使用别名
import matplotlib.pyplot as plt
注意事项
  1. 避免循环导入
  2. 导入语句应放在文件顶部(除特殊情况)
  3. 导入顺序建议:标准库→第三方库→本地模块
  4. 每个导入语句独占一行(除特殊情况)
  5. 避免在函数内部导入模块(除特殊情况)
示例代码
# 标准库
import os
import sys
from datetime import datetime

# 第三方库
import numpy as np
import pandas as pd
from flask import Flask

# 本地模块
from utils.helpers import validate_email
from models.user import User

文档字符串(Docstring)

概念定义

文档字符串是Python中用于解释函数、类或模块用途的特殊字符串。它位于对象定义的第一个语句处,通常用三重引号("""''')包裹。

使用场景
  1. 解释函数/类的功能
  2. 说明参数和返回值
  3. 提供使用示例
  4. 作为自动生成文档的基础
常见格式
def function_name(arg1, arg2):
    """简要描述
    
    详细描述(可选)
    
    Args:
        arg1 (type): 参数说明
        arg2 (type): 参数说明
    
    Returns:
        type: 返回值说明
        
    Example:
        >>> function_name(value1, value2)
        expected_output
    """
    # 函数体

help()函数

基本用法

help()函数用于查看对象的文档字符串:

help(function_name)
交互式使用
  1. 在Python解释器中直接输入help()进入帮助模式
  2. 输入模块/函数名查看帮助信息
  3. 输入q退出帮助模式
示例代码
def calculate_area(radius):
    """计算圆的面积
    
    根据给定的半径计算圆的面积
    
    Args:
        radius (float): 圆的半径(单位:米)
    
    Returns:
        float: 圆的面积(单位:平方米)
        
    Example:
        >>> calculate_area(2.0)
        12.566370614359172
    """
    import math
    return math.pi * radius ** 2

# 查看帮助
help(calculate_area)
注意事项
  1. 文档字符串应简明扼要但信息完整
  2. 保持文档字符串与实际功能同步更新
  3. 复杂的函数/类应该包含示例用法
  4. 遵循PEP 257文档字符串规范

交互式解释器探索技巧

概念定义

交互式解释器(REPL,Read-Eval-Print Loop)是Python提供的即时执行代码的环境,允许用户逐行输入代码并立即查看结果。

使用场景
  1. 快速测试代码片段
  2. 学习新模块或函数
  3. 调试复杂表达式
  4. 探索对象属性和方法
常见误区
  1. 在交互式环境中定义的变量不会自动清除
  2. 多行代码需要正确缩进(使用...提示符时)
  3. 不能直接运行完整脚本(需使用exec()或导入)
实用技巧示例
快速查看帮助
help(len)  # 查看内置函数帮助
?len       # IPython中的简写方式
探索对象
dir(str)        # 查看字符串所有方法
vars(object)    # 查看对象属性
历史记录
_     # 上一个结果
__    # 上上个结果
_2    # 历史记录中第2个输出(IPython专用)
代码补全
import os
os.path.<Tab>  # 在IPython/Jupyter中自动补全
测量执行时间
%timeit [x**2 for x in range(1000)]  # IPython专用
魔法命令(IPython)
%quickref    # 查看快速参考
%history     # 查看命令历史
%run script.py  # 运行外部脚本

性能优化注意事项

概念定义

性能优化是指通过改进代码结构、算法选择或系统配置等手段,提高程序的执行效率、减少资源消耗的过程。

使用场景
  1. 处理大数据量时
  2. 高频调用的核心功能
  3. 响应时间敏感的应用
  4. 资源受限的环境(如移动设备)
常见误区与注意事项
  1. 过早优化:在未确定性能瓶颈前进行优化,可能导致代码可读性下降
  2. 过度优化:为微小性能提升牺牲代码可维护性
  3. 忽略算法复杂度:未选择合适的时间/空间复杂度的算法
  4. 局部优化:优化非关键路径代码
  5. 忽略测量:未使用性能分析工具进行量化评估
  6. 缓存滥用:不合理使用缓存可能导致内存问题
  7. I/O操作:频繁的磁盘/网络访问未做优化
示例代码
# 不优化的版本
result = []
for i in range(10000):
    result.append(i*2)

# 优化后的版本(列表推导式)
result = [i*2 for i in range(10000)]

# 更进一步的优化(生成器表达式)
result = (i*2 for i in range(10000))
优化原则
  1. 先测量后优化(使用timeit、cProfile等工具)
  2. 遵循80/20法则(优化关键20%的代码)
  3. 保持代码可读性
  4. 考虑可维护性
  5. 记录优化前后的性能对比

Python 常见陷阱与解决方案

可变默认参数

Python 中函数的默认参数在函数定义时就被计算并保存,而不是每次调用时重新计算。这会导致使用可变对象(如列表、字典)作为默认参数时出现意外行为。

def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] 而不是预期的 [2]

解决方案:使用 None 作为默认值,在函数内部初始化可变对象。

def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items
循环中修改迭代对象

在循环中直接修改正在迭代的对象会导致意外行为。

numbers = [1, 2, 3, 4]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)
# 结果是 [1, 3] 而不是预期的 [1, 3]

解决方案:迭代对象的副本或使用列表推导式。

numbers = [1, 2, 3, 4]
numbers = [num for num in numbers if num % 2 != 0]
变量作用域混淆

在函数内部对变量赋值会创建一个新的局部变量,而不是修改外部变量。

x = 10
def func():
    x = 20  # 创建新的局部变量
func()
print(x)  # 仍然是 10

解决方案:使用 global 关键字声明全局变量。

x = 10
def func():
    global x
    x = 20
func()
print(x)  # 现在是 20
浮点数精度问题

由于二进制浮点数的表示方式,某些十进制小数无法精确表示。

0.1 + 0.2 == 0.3  # 返回 False

解决方案:使用 math.isclose() 或 decimal 模块进行精确比较。

import math
math.isclose(0.1 + 0.2, 0.3)  # 返回 True
is 和 == 的混淆

is 比较对象标识(内存地址),== 比较值。

a = [1, 2, 3]
b = [1, 2, 3]
a == b  # True
a is b  # False

解决方案:明确比较目的,值比较用 ==,对象标识比较用 is。

你可能感兴趣的:(python,开发语言)