1. 函数基础概念解析
在Python编程中,函数就像厨房里的多功能料理机——你把食材(参数)放进去,选择功能(函数逻辑),它就能输出加工好的菜品(返回值)。这种封装思想让代码更模块化,也大幅提升了开发效率。
1.1 为什么需要函数
假设你要在程序中反复计算圆的面积,没有函数时代码会是这样:
radius1 = 5 area1 = 3.14 * radius1 ** 2 radius2 = 8 area2 = 3.14 * radius2 ** 2 # 每次计算都要重复写公式使用函数后:
def circle_area(radius): return 3.14 * radius ** 2 print(circle_area(5)) # 调用一次 print(circle_area(8)) # 再调用一次实际工程中建议用math.pi替代3.14,这里为简化示例保留字面值
1.2 函数定义解剖
一个标准函数定义包含这些关键部分:
def 函数名(参数1, 参数2=默认值): """文档字符串(docstring)""" 函数体代码 return 返回值例如银行账户转账函数:
def transfer(sender, receiver, amount, currency='CNY'): """执行账户间转账 Args: sender: 转出账户 receiver: 转入账户 amount: 转账金额 currency: 货币类型,默认为人民币 """ if sender.balance >= amount: sender.balance -= amount receiver.balance += amount return True return False2. 参数传递深度解析
2.1 参数传递机制
Python的参数传递既不是纯值传递也不是引用传递,而是"对象引用传递"。理解这点对避免bug至关重要:
def modify_list(items): items.append(4) # 会修改原始列表 items = [7,8,9] # 新建局部变量 my_list = [1,2,3] modify_list(my_list) print(my_list) # 输出[1,2,3,4]而非[7,8,9]2.2 参数类型实战
位置参数:最常见的传参方式
def power(base, exponent): return base ** exponent print(power(2, 3)) # 8关键字参数:提高可读性
print(power(exponent=3, base=2)) # 同样输出8默认参数:注意可变对象陷阱
# 错误示范 def add_item(item, items=[]): items.append(item) return items # 正确做法 def add_item(item, items=None): items = [] if items is None else items items.append(item) return items可变参数:处理不定数量输入
def average(*numbers): return sum(numbers) / len(numbers) if numbers else 0 print(average(1,2,3,4)) # 2.5
3. 函数高级特性
3.1 闭包与装饰器
闭包就像给函数装了个"记忆芯片":
def counter(): count = 0 def increment(): nonlocal count count += 1 return count return increment my_counter = counter() print(my_counter()) # 1 print(my_counter()) # 2装饰器则是函数的"功能扩展坞":
def log_time(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) print(f"{func.__name__}执行耗时: {time.time()-start:.2f}s") return result return wrapper @log_time def heavy_calculation(): time.sleep(1) heavy_calculation() # 自动输出执行时间3.2 生成器函数
生成器是"懒加载"的数据流:
def fibonacci(limit): a, b = 0, 1 while a < limit: yield a a, b = b, a + b for num in fibonacci(1000): print(num) # 逐个生成,不占内存4. 函数最佳实践
4.1 函数设计原则
单一职责原则:每个函数只做一件事
# 不好 def process_data(data): data = clean_data(data) result = analyze(data) save_to_db(result) # 更好 def pipeline(data): data = clean(data) result = analyze(data) persist(result)合理控制函数长度:通常不超过50行
避免副作用:除非必要,不要修改外部状态
4.2 性能优化技巧
使用局部变量加速访问:
def fast_calc(): local_sqrt = math.sqrt # 局部变量查找更快 return [local_sqrt(x) for x in range(1000)]用缓存装饰器优化重复计算:
from functools import lru_cache @lru_cache(maxsize=128) def factorial(n): return n * factorial(n-1) if n else 1
5. 常见问题排查
5.1 参数错误集锦
TypeError:参数数量/类型不匹配
def greet(name): print(f"Hello {name}") greet() # TypeError: missing 1 required positional argumentUnboundLocalError:变量作用域混淆
x = 10 def func(): print(x) # 报错 x = 20
5.2 调试技巧
使用
inspect模块检查函数:import inspect print(inspect.signature(power)) # 显示参数签名断点调试:
import pdb def buggy_func(): x = 1 pdb.set_trace() # 在此暂停 return x + '1' # 故意制造错误
在Python控制台输入help(函数名)可以查看函数的docstring,这是交互式开发时快速了解函数用法的好习惯。对于复杂项目,建议使用类型注解(Type Hints)来提升代码可维护性:
from typing import List, Dict def process_items(items: List[str], config: Dict[str, int]) -> bool: """处理字符串列表""" return len(items) == config.get('threshold', 0)