
写出更简洁、更聪明的 Python 函数
许多开发者,包括经验丰富的老手,在编写 Python 函数时都会不自觉地陷入一些常见陷阱。这些做法短期内或许不会引发问题,但随着代码库的增长,它们会导致代码变得难以维护、效率低下。
如果你对 Python 函数的理解还停留在“能跑就行”,现在是时候升级你的认知了。了解这些常见误区并采用最佳实践,能让你的代码焕然一新。
1. 避免使用可变对象作为默认参数
错误示例
Python 在函数定义时只会初始化一次默认参数,而不是每次调用时都初始化。这意味着多次调用会共享同一个可变对象(如列表),导致意外的副作用。
def add_item(item, items=[]):
items.append(item)
return items
print(add_item('apple')) # ['apple']
print(add_item('banana')) # ['apple', 'banana'] ???
正确做法
当默认值需要是可变对象时,应将其设为 None,并在函数内部进行初始化。
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item('apple')) # ['apple']
print(add_item('banana')) # ['banana']
2. 保持返回值类型一致
错误示例
返回不一致的数据类型(如字符串和整数)会使函数调用方难以处理,并埋下类型错误的隐患。
def process(value):
if value > 10:
return "Success"
else:
return 0 # 混合了 str 和 int
正确做法
返回 None 或保持单一返回值类型,使函数行为可预测。
from typing import Optional
def process(value: int) -> Optional[str]:
return "Success" if value > 10 else None
3. 遵循单一职责原则:保持函数小而专一
错误示例
一个函数承担了过多职责(计算、加税、折扣、运费),导致逻辑复杂、难以测试和复用。
def calculate_price(quantity, price, tax_rate, discount, shipping):
total = (quantity * price) + shipping
total += total * tax_rate
if discount:
total -= total * discount
return total
正确做法
将复杂功能拆分为多个单一职责的小函数,每个函数只做一件事。
def calculate_subtotal(quantity, price):
return quantity * price
def apply_tax(subtotal, tax_rate):
return subtotal + (subtotal * tax_rate)
def apply_discount(amount, discount):
return amount - (amount * discount)
def calculate_total(quantity, price, tax_rate, discount, shipping):
subtotal = calculate_subtotal(quantity, price)
taxed_total = apply_tax(subtotal, tax_rate)
discounted_total = apply_discount(taxed_total, discount)
return discounted_total + shipping
4. 优先使用 f-strings 进行字符串格式化
错误示例
旧式的 % 格式化或 .format() 方法可读性较差,且效率不如 f-strings。
def greet(name, age):
return "Hello, my name is %s and I am %d years old." % (name, age)
或
def greet(name, age):
return "Hello, my name is {} and I am {} years old.".format(name, age)
正确做法
f-strings 语法更简洁、直观,是 Python 3.6+ 推荐的字符串格式化方式。
def greet(name, age):
return f"Hello, my name is {name} and I am {age} years old."
5. 使用类型注解提升代码清晰度
错误示例
没有类型提示的函数,其参数和返回值的意图不明确。
def add_numbers(a, b):
return a + b
正确做法
添加类型注解(Type Hints)可以使函数接口自文档化,并有助于静态类型检查工具发现错误。
def add_numbers(a: int, b: int) -> int:
return a + b
6. 使用 enumerate() 替代手动索引
错误示例
在循环中手动维护索引变量既繁琐又容易出错。
fruits = ["Mango", "Pineapple", "Guava"]
index = 0
for fruit in fruits:
print(f"{index}: {fruit}")
index += 1
正确做法
enumerate() 函数能同时获取索引和元素,使代码更简洁、更 Pythonic。
fruits = ["Mango", "Pineapple", "Guava"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
7. 避免使用 try-except 进行常规流程控制
错误示例
使用异常处理来检查字典键是否存在,是一种“请求原谅比许可容易”(EAFP)的过度使用,在这里并不合适。
def get_price(data):
try:
return data["price"]
except KeyError:
return 0
正确做法
对于简单的键值查找,使用 .get() 方法更清晰、更高效。
def get_price(data):
return data.get("price", 0)
总结
编写优秀的 Python 函数,目标远不止于“能运行”。通过避免上述常见陷阱并采纳最佳实践——如使用不可变默认值、保持函数单一职责、利用类型注解和现代语法特性——你可以显著提升代码的可读性、可维护性和性能。
将这些原则应用到你的既有代码中,你会发现代码变得更加清晰和健壮。
关注“鲸栖”小程序,掌握最新AI资讯
本文由鲸栖原创发布,未经许可,请勿转载。转载请注明出处:http://www.itsolotime.com/archives/13560
