应使用命名常量或枚举替代魔法数字:如HTTP_OK=200、ADULT_AGE=18、OrderStatus.PAID=1等,提升可读性、可维护性与类型安全。

直接在分支判断里写数字(比如 if status == 3: 或 if score >= 90:)就是典型的“魔法数字”问题——这些数字没有名字、没有上下文,别人读代码时得猜它代表什么,改起来也容易出错。
用命名常量替代魔法数字
把反复出现、有业务含义的数字定义成大写变量名,放在模块顶部或配置类中:
-
状态码场景:把
if code == 200:改成if code == HTTP_OK:,并提前定义HTTP_OK = 200 -
业务阈值场景:把
if age >= 18:改成if age >= ADULT_AGE:,定义ADULT_AGE = 18 -
枚举型取值场景:订单状态
if order.status == 1:→if order.status == ORDER_PAID:,配合ORDER_PAID = 1、ORDER_CANCELLED = 2等
推荐使用 Enum 类提升可维护性
比普通常量更进一步,用 enum.Enum 把相关常量组织成一个类型,自带校验和语义:
- 定义:
from enum import Enum; class OrderStatus(Enum): PAID = 1; SHIPPED = 2; CANCELLED = 3 - 使用:
if order.status == OrderStatus.PAID:—— 一眼看懂含义,IDE 还能自动补全、防止拼错 - 优势:避免不同模块间常量名冲突;序列化/日志中显示
OrderStatus.PAID而不是模糊的1
注意边界值和组合逻辑的常量化
不只是单个数字,连带条件中的范围、组合规则也应抽象:
- 别写
if score >= 90 and score ,改用if GRADE_A_MIN - 多个条件共用同一含义时,统一提取:比如“有效邮箱”判断涉及长度、@符号、域名格式,可封装为
is_valid_email()函数,而不是在 if 里堆逻辑 - 避免“数字+注释”式妥协:
if status == 4: # 表示已归档—— 注释会过时,不如直接用if status == STATUS_ARCHIVED:
实际替换小技巧
重构时不用一次全改,可以分步走:
- 先全局搜索该数字(如
404),确认所有出现位置是否真代表同一含义 - 新建常量后,逐个替换,并运行测试验证行为不变
- 对旧代码加临时警告(如
warnings.warn("使用魔法数字 404,请改用 HTTP_NOT_FOUND", DeprecationWarning))辅助过渡










