Python 最佳实践
以下是一份 系统、清晰、实用 的《Python 最佳实践》合集,覆盖代码风格、项目结构、性能、安全、测试、并发、调试、数据库、类型标注等方向。作为长期写 Python 的开发者,你照着这些实践写代码,就会很“专业”。
✅ Python 最佳实践(2025 版,全方位指南)
不用纠结空格换行,自动化工具最省心:
pip install black
black your_project/
- snake_case -> 变量、函数
- PascalCase -> 类
- CONSTANT_CASE -> 常量
- 避免中文拼音
每个函数只做“一件事”。
比 % 和 .format 更直观:
name = "martin"
print(f"Hello {name}")
推荐的项目结构:
project/
app/
__init__.py
models/
api/
services/
utils/
tests/
config/
requirements.txt
README.md
原则:模块按照功能分层,而不是按照文件类型分层。
尽可能使用集合运算、字典查询(O(1))。
result = [f(x) for x in items]
def read_lines(path):
with open(path) as f:
for line in f:
yield line
from functools import lru_cache
@lru_cache(None)
def fib(n):
...
比 input()/print() 更快:
import sys
sys.stdin.readline()
sys.stdout.write()
适合网络请求、数据库、读写文件。
不要用多线程(会被 GIL 卡住)。
async with session.get(url) as resp:
return await resp.text()
如果用,必须加 sandbox 或 ast 限制。
使用环境变量读取:
import os
password = os.getenv("DB_PASSWORD")
如:token、密码、手机号。
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s"
)
logging.info("start server")
try:
...
except ValueError:
...
错误必须记录 log。
class LoginError(Exception):
pass
函数应该行为可预测。
每个类只负责一个功能。
优先使用组合(composition over inheritance)。
from typing import List, Dict, Optional
def add(x: int, y: int) -> int:
return x + y
pip install mypy
mypy your_project/
Arrange -> Act -> Assert
def test_add():
assert add(1, 2) == 3
@pytest.fixture
def db():
...
python3 -m venv venv
pip freeze > requirements.txt
如果是高级项目:
推荐使用 poetry。
from pathlib import Path
p = Path("data/file.txt")
跨平台无脑好用。
避免 SQL 注入。
Service 层不能直接操作 Session。
使用 pydantic。
数据库、权限、配置。
保持后端接口输出一致。
写 Python,就是要把内置工具吃透。
例:
from collections import Counter
Counter(words)
参考 Function (函数) 中的最佳实践部分。
简单的函数,例如 list append, 可以使用 next/map/filter/lambda 优化重写
数据在前,其它在后
- 有明确返回类型,比如 str、list、dict,正常返回对应类型的数据,异常返回对应类型的 False 值
- 没有明确返回类型,加一个 None
这样使用 if 就可以很方便的判断数据是否有效。
# 正常返回 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 中发布。