📢 转载信息
原文链接:https://www.kdnuggets.com/how-to-write-readable-python-functions-even-if-youre-a-beginner
原文作者:Bala Priya C
Image by Author
# 引言
你写下了你的第一个 Python 函数。它能运行。你运行它,它产生正确的输出,你感受到了完成的喜悦。然后两周后你再看它,心想:“这玩意儿到底在干什么?”
编写可读性高的 Python 函数与聪明或高级无关。它关乎于编写能够清晰传达意图、干净地处理其职责、并使后来者的工作更轻松的函数。
让我们学习如何编写读起来像优美散文,而不是让读者难以理解的神秘谜题的函数。
# 1. 像对朋友解释一样命名你的函数
函数名是人们首先阅读的内容。一个好的名字应该让你确切地知道函数的作用,而无需阅读其内部代码。
反例:
def proc(d): return sum(d) / len(d)
正例:
def calculate_average(numbers): return sum(numbers) / len(numbers)
函数名 calculate_average 使用了动词(“calculate”),告诉你它执行一个动作,后接它计算的内容(“average”)。参数 numbers 清楚地表明它期望一个数值集合。
函数体使用 sum(numbers) 对所有值求和,使用 len(numbers) 计算数量,然后相除得出平均值。任何阅读此代码的人都能立即理解其作用,无需注释或文档。
# 2. 使用描述性的参数名称
单字母变量或许能节省输入时间,但会牺牲可读性。参数是你函数的输入,所以要清楚地说明你期望什么。
反例:
def discount(p, r): return p * (1 - r)
正例:
def apply_discount(original_price, discount_rate): return original_price * (1 - discount_rate)
现在,任何阅读 apply_discount(100, 0.2) 的人都明白你正在对 100 应用 20% 的折扣。代码是自文档化的。你无需检查函数定义就能理解应该传入什么参数。
# 3. 保持函数简短和专注
函数应该做好一件事。如果你的函数有多个职责,那么它将难以测试、复用和理解。因此,将复杂逻辑分解成更小、更专注的函数。
反例:
def process_order(items, customer_email, discount_code): # Calculate total subtotal = sum(item["price"] * item["quantity"] for item in items) # Apply discount if discount_code == "SAVE10": discount = 0.10 elif discount_code == "SAVE20": discount = 0.20 else: discount = 0 total = subtotal * (1 - discount) # Send email subject = f"Order Confirmation" body = f"Your order total is ${total:.2f}" send_email(customer_email, subject, body) return total
正例:
def calculate_order_subtotal(items): return sum(item["price"] * item["quantity"] for item in items) def get_discount_rate(discount_code): discount_rates = {"SAVE10": 0.10, "SAVE20": 0.20} return discount_rates.get(discount_code, 0) def apply_discount_to_subtotal(subtotal, discount_rate): return subtotal * (1 - discount_rate) def send_order_confirmation_email(customer_email, total): subject = "Order Confirmation" body = f"Your order total is ${total:.2f}" send_email(customer_email, subject, body) def process_order(items, customer_email, discount_code): subtotal = calculate_order_subtotal(items) discount_rate = get_discount_rate(discount_code) total = apply_discount_to_subtotal(subtotal, discount_rate) send_order_confirmation_email(customer_email, total) return total
现在每个函数都有一个单一的、明确的目的。主函数 process_order 读起来就像一个食谱:计算小计,获取折扣,应用折扣,发送邮件,返回总计。
# 4. 添加文档字符串 (Docstrings) 来解释目的
函数名告诉你函数的作用,但 文档字符串会解释它为何存在、它期望什么以及它返回什么。这对于复杂的逻辑或非显而易见的行为尤其有帮助。
正例:
def calculate_shipping_cost(weight_kg, distance_km, is_express=False): """ Calculate shipping cost based on package weight and distance. Args: weight_kg (float): Package weight in kilograms distance_km (float): Shipping distance in kilometers is_express (bool): Whether to use express shipping (default: False) Returns: float: Total shipping cost in dollars Example: >>> calculate_shipping_cost(5.0, 100, is_express=True) 45.50 """ base_rate = 2.50 per_kg_rate = 1.20 per_km_rate = 0.15 express_multiplier = 2.0 if is_express else 1.0 cost = ( base_rate + (weight_kg * per_kg_rate) + (distance_km * per_km_rate) ) * express_multiplier return round(cost, 2)
文档字符串解释了每个参数的含义、应有的类型以及函数返回的内容。任何使用此函数的人都确切地知道如何调用它,而无需阅读其实现。
# 5. 在函数内部使用清晰的变量名
就像参数一样,内部变量也应该具有描述性。不要让人们去解码缩写或猜测 tmp 或 x 代表什么。
反例:
def calc_bmi(w, h): h_m = h / 100 res = w / (h_m**2) return round(res, 1)
正例:
def calculate_bmi(weight_kg, height_cm): height_meters = height_cm / 100 bmi = weight_kg / (height_meters**2) return round(bmi, 1)
变量 height_meters 确切地告诉你发生了哪种转换。如你所见,变量 bmi 存储了身体质量指数(BMI)的计算结果。
# 6. 避免“魔法数字”;使用命名常量代替
散布在代码中的数字是“魔法数字”,意味着它们的用途不明确。给它们起一个有意义的名字,这样读者就能理解它们的意义。
反例:
def calculate_late_fee(days_overdue): if days_overdue <= 7: return days_overdue * 2 else: return 14 + (days_overdue - 7) * 5
正例:
def calculate_late_fee(days_overdue): DAILY_FEE_FIRST_WEEK = 2 GRACE_PERIOD_DAYS = 7 BASE_FEE_AFTER_GRACE = 14 DAILY_FEE_AFTER_GRACE = 5 if days_overdue <= GRACE_PERIOD_DAYS: return days_overdue * DAILY_FEE_FIRST_WEEK else: days_after_grace = days_overdue - GRACE_PERIOD_DAYS return BASE_FEE_AFTER_GRACE + (days_after_grace * DAILY_FEE_AFTER_GRACE)
现在费用结构很明显了。常量记录了你的业务规则。当费率发生变化时,你只需更新一个命名清晰的值,而不是去搜索神秘的数字。
# 7. 使用类型提示来增强清晰度
类型提示会告诉读者你的函数期望和返回 什么类型。这可以防止混淆并尽早捕获错误。在函数中添加类型提示是一种良好的实践。
正例:
def format_user_greeting(user_name: str, age: int, is_member: bool = False) -> str: membership_status = "member" if is_member else "guest" return f"Hello {user_name}, age {age}. You are a {membership_status}."
类型提示清楚地表明:user_name 是一个字符串,age 是一个整数,is_member 是一个布尔值(默认为 False),并且函数返回一个字符串。你的集成开发环境(IDE)可以利用这些信息提供更好的自动补全和错误检查。
# 结论
可读性高的函数并非更难编写。它们只是要求你站在用户的角度思考。你所做的每一个选择——命名、结构、注释——都在帮助或阻碍理解。
目标不是完美的代码。目标是清晰传达的代码。目标是让下一个人说“啊,我明白了”,而不是“这到底在干嘛?”的代码。这就是可读的代码,你可以从第一天就开始编写它。
在下一篇文章中,我们将学习如何编写干净的 Python 类。在此之前,请继续编码!
Bala Priya C 是来自印度的一名开发者和技术作家。她喜欢在数学、编程、数据科学和内容创作的交叉点上工作。她的兴趣和专长领域包括 DevOps、数据科学和自然语言处理。她喜欢阅读、写作、编码和咖啡!目前,她正致力于通过撰写教程、操作指南、观点文章等内容,学习并将自己的知识与开发者社区分享。Bala还创建引人入胜的资源概述和编码教程。
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区