Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Python 最佳实践

以下是一份 系统、清晰、实用 的《Python 最佳实践》合集,覆盖代码风格、项目结构、性能、安全、测试、并发、调试、数据库、类型标注等方向。作为长期写 Python 的开发者,你照着这些实践写代码,就会很“专业”。

✅ Python 最佳实践(2025 版,全方位指南)

1. 代码风格最佳实践(PEP8 + 实战经验)

使用 Black 统一格式

不用纠结空格换行,自动化工具最省心:

pip install black
black your_project/

变量、函数、类命名规范

  • snake_case -> 变量、函数
  • PascalCase -> 类
  • CONSTANT_CASE -> 常量
  • 避免中文拼音

避免过长函数(>50 行需拆分)

每个函数只做“一件事”。

使用 f-string

%.format 更直观:

name = "martin"
print(f"Hello {name}")

2. 项目结构最佳实践

推荐的项目结构:

project/
    app/
        __init__.py
        models/
        api/
        services/
        utils/
    tests/
    config/
    requirements.txt
    README.md

原则:模块按照功能分层,而不是按照文件类型分层。

3. 性能最佳实践

避免不必要的循环嵌套

尽可能使用集合运算、字典查询(O(1))。

使用列表推导替代 append

result = [f(x) for x in items]

使用生成器惰性计算(尤其是大数据)

def read_lines(path):
    with open(path) as f:
        for line in f:
            yield line

使用 lru_cache 做缓存

from functools import lru_cache

@lru_cache(None)
def fib(n):
    ...

快速 I/O

input()/print() 更快:

import sys
sys.stdin.readline()
sys.stdout.write()

4. 并发最佳实践

I/O 密集 -> 用 asyncio

适合网络请求、数据库、读写文件。

CPU 密集 -> 用 multiprocessing

不要用多线程(会被 GIL 卡住)。

使用异步上下文

async with session.get(url) as resp:
    return await resp.text()

5. 安全最佳实践

永远不要信任 eval

如果用,必须加 sandbox 或 ast 限制。

不要把密码硬编码

使用环境变量读取:

import os
password = os.getenv("DB_PASSWORD")

Logging 不打印敏感信息

如:token、密码、手机号。

6. logging 最佳实践

使用 logging 而不是 print

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)

logging.info("start server")

默认等级使用 INFO / WARNING,不要全用 DEBUG

7. 异常最佳实践

捕获具体异常,不要用 except Exception

try:
    ...
except ValueError:
    ...

不吞异常

错误必须记录 log。

写自己的业务异常类

class LoginError(Exception):
    pass

8. 函数/类设计最佳实践

明确输入输出,避免隐式行为

函数应该行为可预测。

单一职责

每个类只负责一个功能。

不要滥用继承

优先使用组合(composition over inheritance)。

9. 类型标注最佳实践(PEP 484)

使用 Python typing(尤其是 FastAPI)

from typing import List, Dict, Optional

def add(x: int, y: int) -> int:
    return x + y

使用 mypy 静态检查

pip install mypy
mypy your_project/

10. 测试最佳实践(pytest)

单元测试三要素

Arrange -> Act -> Assert

def test_add():
    assert add(1, 2) == 3

使用 fixture

@pytest.fixture
def db():
    ...

11. 环境管理最佳实践

使用 venv 或 conda

python3 -m venv venv

使用 requirements.txt 管理依赖

pip freeze > requirements.txt

如果是高级项目:

推荐使用 poetry。

12. 文件、路径最佳实践

使用 pathlib 而不是 os.path

from pathlib import Path

p = Path("data/file.txt")

跨平台无脑好用。

13. 数据库最佳实践

使用 ORM(SQLAlchemy)

不拼接 SQL 字符串

避免 SQL 注入。

定义 Repository 层

Service 层不能直接操作 Session。

14. API 最佳实践(FastAPI)

统一 response schema

使用 pydantic。

使用 Depends 管理依赖

数据库、权限、配置。

全局异常处理

保持后端接口输出一致。

15. 常用工具最佳实践

使用 pathlib、functools、itertools、collections

写 Python,就是要把内置工具吃透。

例:

from collections import Counter
Counter(words)

函数

参考文档

参考 Function (函数) 中的最佳实践部分。

简单的函数,例如 list append, 可以使用 next/map/filter/lambda 优化重写

参数

数据在前,其它在后

为了判断返回的数据是否有效(为True)

  • 有明确返回类型,比如 str、list、dict,正常返回对应类型的数据,异常返回对应类型的 False 值
  • 没有明确返回类型,加一个 None

这样使用 if 就可以很方便的判断数据是否有效。

使用 try 包裹主体

示例

# 正常返回 list,异常返回 list 的 False 值 []
def map_filter(iterable: Iterable, func: Callable) -> list:
    """对 iterable 执行 func, 并保留为 True 的返回值"""
    try:
        return [x for x in map(func, iterable) if x]
    except Exception as e:
        if DEBUG:
            logger.exception(e)
        else:
            logger.error(e)
        return []

# 没有明确返回类型,加一个 None
def timestamp_to_datetime(timestamp: int | float, tz: timezone = timezone.utc) -> datetime | None:
    """Unix Timestamp 转换为 Datatime"""
    try:
        if not isinstance(timestamp, (int, float)):
            return None
        return (datetime.fromtimestamp(timestamp, tz=tz)).replace(tzinfo=None)
    except Exception as e:
        if DEBUG:
            logger.exception(e)
        else:
            logger.error(e)
        return None

# 判断并处理

n = map_filter(...)
if not n:
    ....

m = timestamp_to_datetime(...)
if not m:
    ....

笔记

类和实例

类在没有实例化之前不能直接调用类的方法

  • modules/database.py 定义了 database 类
  • main.py 将创建了 database 类 的实例化, 并调用其中的方法

多线程要写在类的内部, 在类的外部使用多线程调用类的方法会有问题.

循环

while 一定要添加 sleep,否则可能因为循环过快或者逻辑不合理导致 CPU 使用率很高。

  • 通过程序日志的刷新速度,glances命令,查看和判断 CPU 的使用率。

公用包

如何调试公用包?直接复制相关的文件到当前目录,修改 import,调试完以后,在 ezkit 中发布。