当前位置:首页>python>停止在 Python 中编写工具函数(这里有更好的模式)!

停止在 Python 中编写工具函数(这里有更好的模式)!

  • 2026-10-12 06:24:05
停止在 Python 中编写工具函数(这里有更好的模式)!

utils.py 的诱人谎言

在每个 Python 项目中,总会在某个时候冒出一个熟悉的想法:

“这个逻辑以后或许有用。我先把它放到 utils.py 里 。”

感觉很负责,很有前瞻性,几乎达到了专业水准。

短期内,这招确实管用。

六个月过去,utils.py 已经长达 1200 行。几乎没人记得其中一半函数是做什么用的。新来的开发者不敢碰它。老开发者宁愿复制粘贴也不愿重写——因为找到合适的工具比重写它要难得多。

如果你觉得这似曾相识,你并不孤单。

工具函数是不断增长的 Python 代码库中最常见(也是最有害)的模式之一。

当然,请注意,本文并非建议永远不要重用代码。而是想告诉你:停止将不相关的行为集中到通用的效用函数中。

工具函数通常都是出于良好的初衷:

•
避免重复
•
把逻辑集中在一个地方
•
让某些东西可重复利用
•
编写 DRY()Don't Repeat Yourself代码

你会看到类似这样的文件:

utils.pyhelpers.pycommon.pyshared.py

它们里面是什么?

•
字符串格式化辅助函数
•
日期解析
•
验证逻辑
•
API 响应塑形
•
业务规则(伪装成辅助函数)

问题不在于重复利用,而在于脱离上下文的重用。

工具提供了灵活性,但它们却悄无声息地剥夺了其意义。

真正的问题在于:工具函数隐藏了上下文

当你读到这样的代码时:

from utils import format_date, validate_input, process_data

你几乎什么也学不到。

•
什么样的日期?
•
验证输入内容是什么?
•
处理哪些数据?

工具函数隐藏了意图,它们将领域知识扁平化为模糊的动词。

现在将其与以下内容进行比较:

from billing.dates import format_invoice_datefrom auth.validation import validate_login_payloadfrom orders.processing import process_pending_orders

同样的重用,但清晰度截然不同。

上下午是可读代码与晦涩代码之间的区别。

为什么工具函数无法扩展

过于庞大的工具代码库可能会以可预测的方式失败。

1. 它们变成了杂物抽屉

任何不适合放在其他任何地方的东西都会被放到工具类中。

最终:

•
所有权不明
•
没有明确的责任人
•
没有明确的界限

每一项新增功能都显得合情合理。没有任何一项功能被移除。

2. 它们积累了隐藏的业务逻辑

最初只是“一个助手”,后来逐渐发展出规则:

def calculate_discount(price, user):    if user.is_premium:        return price * 0.8    return price

那不是工具,而是伪装成通用逻辑的业务逻辑。

一旦业务规则存在于工具类中,它们就会变得:

•
难以测试
•
容易被滥用
•
修改将会很危险

3. 它们会在你不知不觉中形成紧密耦合

工具函数通常:

•
导入模型
•
取决于设置
•
假设数据形状
•
依赖副作用

但因为它们是“辅助函数”,开发人员对待它们不像对待核心逻辑那样谨慎。

更深层次的问题:工具程序是一种设计缺陷

在设计良好的系统中:

•
行为与其所依赖的数据密切相关。
•
逻辑有其明确的归宿
•
名称反映的是意图,而不是实现方式。

工具函数违反了这三点。

它们之所以存在,是因为我们一直在回避一个更难的问题:

“这种逻辑属于哪里?”

更好的模式:行为应有意义

与其问,“我可以重复使用吗?”

而应该问:“这种行为代表了什么概念?”

然后将这种行为与该概念联系起来。

让我们来看看这在实践中的含义是什么。

模式一:将行为移入领域模块

不要使用全局的 utils.py,而是按领域进行组织。

以前:

# utils.pydef is_valid_email(email):    ...

现在:

# users/validation.pydef is_valid_email(email: str) -> bool:    ...

现在这个功能终于有了归宿。

它讲述了一个故事:这种逻辑之所以存在,是因为用户存在。

模式二:优先选择小型、功能明确的模块,而非大型工具程序

Python 模块很便宜且都是经过优化的,尽量使用它们。

而不是使用一个巨大的辅助文件utils.py。

而应该使用:

dates.pymoney.pystrings.pyserialization.py

更好的选择:

billing/money.pyorders/serialization.pyreports/dates.py

你不仅仅是在整理代码。

更是在对意图进行编码。

模式 3:当状态或规则至关重要时,请使用类

如果一个函数依赖于规则、配置或不断变化的行为——它可能不是一个工具函数。

以前:

def calculate_tax(amount, country):    ...

现在:

class TaxCalculator:    def __init__(self, country):        self.country = country    def calculate(self, amount):        ...

这将使你获得:

•
显式依赖关系
•
更便捷的测试
•
清晰的延伸点

类并非总是必要的——但人们常常使用工具函数来代替适当的抽象。

模式 4:让数据具有自主行为

行为邻近性(behavioral proximity) 是 Python 中最被低估的模式之一。

如果逻辑操作作用于某个对象,请考虑将其添加到该对象上。

以前:

def is_order_refundable(order):    ...

现在:

class Order:    def is_refundable(self) -> bool:        ...

现在你的代码读起来就像英文一样:

if order.is_refundable():    ...

那不仅仅是更简洁,这样写的代码更诚实。

模式 5:使用功能组合——而功能桶

函数式辅助函数并不坏。

但它们的非结构化集合并不好。

不要将辅助函数集中在一起,而是按管道或转换进行分组。

# parsing.pydef parse_csv(...)def normalize_headers(...)# validation.pydef validate_schema(...)def validate_constraints(...)

现在,重用是通过组合实现的,而不是通过便利实现的。

但编写工具函数的速度更快

这就是它们如此危险的原因。

工具函数优化的是今天的速度,而不是明天的清晰度。

成本不会立即显现,

而是在以下情况才会展现出来:

•
新人熟悉费时费力
•
重构感觉有风险
•
“共享”代码中出现错误
•
没有人知道哪些改变是安全的

良好的设计起初可能会感觉速度较慢,但之后速度会显著提升。

什么时候工具函数式可以接受的

是的,凡事都有例外。

工具函数在满足以下条件时才有意义:

•
纯净(无副作用)
•
无状态
•
与上下文无关
•
真正通用

例如:

•
数学助手
•
简单字符串规范化
•
格式化原语
•
通用解析辅助函数

如果一个函数在任何项目中都适用,那么它很可能是一个工具函数。

但如果它只适用于单个项目,那么它就需要一个合适的归宿。

一个简单的试金石测试

创建工具函数之前,请先问自己:

1
这种逻辑属于某个特定领域吗?
2
它是否对业务规则进行编码?
3
它是否假定某些数据形状?
4
如果项目背景发生变化,它的名称会改变吗?

如果您对以上任何问题回答“是”——

那它就不是一个工具函数。

结论:停止在辅助函数中隐藏含义

工具函数感觉无害。

它们觉得自己能帮上忙。

它们觉得自己很有成就感。

但随着时间的推移,它们会悄无声息地抹去代码中的含义。

当代码清晰、易读且诚实地表达意图时,Python 的优势就得以充分展现。

这并非来自庞大的辅助文件,而是来自恰当的行为。

所以,下次当你的手指敲击 utils.py 时 ,请稍作停顿。

问问自己,逻辑究竟属于哪里。

未来的你和你的队友都会感谢你。

Thanks for your reading!

Enjoying coding, my friends! 🧑‍💻🧑‍💻🧑‍💻💯💯💯


推荐阅读👇👇👇

•
写给 Python 开发者的“内功心法”:23 种经典设计模式系列 (开篇)
•
一文搞懂大语言模型(LLMs)的工作原理!
•
机器学习数学概念:从苹果的掉落彻底搞懂导数(Derivatives)
•
什么是大语言模型(LLM)?通俗易懂的介绍
•
一文彻底搞懂机器学习中的梯度(Gradient)到底是什么东西!
•
Python 必知必会:让初学者变身建造者的 10 个 Python 技巧!
•
Python 必知必会:7 个 Python 库——可以处理 Excel 无法处理的一切!)

🌟 如果你觉得这篇文章对你有帮助,并且愿意支持我的话,你可以: 🌟

•
👍 点赞,让文章获得系统推荐
•
⤴️ 分享,把内容传递给身边的伙伴
•
❤️ 推荐,让文章影响到更多人
•
👏 欢迎留言交流,一起拓展技术的边界

👇👇👇 Follow me,获取更多高质量干货分享,我们下期再见!

最新文章

随机文章