Python 第十一节 函数用法详解及使用注意事项
·
前言
Python 中函数分为具名函数(def)和匿名函数(lambda)
1. 函数基本语法
函数定义与调用
def function_name(parameters):
"""文档字符串(可选)"""
# 函数体
return value # 可选
# 调用函数
result = function_name(arguments)
基础示例
def greet(name):
"""返回问候语"""
return f"Hello, {name}!"
print(greet("Alice")) # 输出: Hello, Alice!
2. 参数类型详解
2.1 位置参数
def introduce(name, age, city):
"""位置参数:必须按顺序传递"""
return f"{name} is {age} years old and lives in {city}."
print(introduce("Alice", 25, "Beijing"))
# 输出: Alice is 25 years old and lives in Beijing.
2.2 默认参数
def greet_person(name, greeting="Hello", punctuation="!"):
"""默认参数:调用时可省略"""
return f"{greeting}, {name}{punctuation}"
print(greet_person("Bob")) # 输出: Hello, Bob!
print(greet_person("Charlie", "Hi")) # 输出: Hi, Charlie!
print(greet_person("David", "Hey", ".")) # 输出: Hey, David.
注意事项:
# 错误:默认参数必须是不可变对象
def bad_function(arg=[]): # 危险!
arg.append(1)
return arg
# 正确:使用None作为默认值
def good_function(arg=None):
if arg is None:
arg = []
arg.append(1)
return arg
2.3 关键字参数
def create_profile(name, age, city, country="China"):
"""关键字参数:按参数名传递"""
return f"{name}, {age}, from {city}, {country}"
# 多种调用方式
print(create_profile("Alice", 25, "Beijing"))
print(create_profile(name="Bob", age=30, city="Shanghai"))
print(create_profile(city="Guangzhou", name="Charlie", age=28))
2.4 可变参数 *args
def sum_numbers(*args):
"""*args 接收任意数量的位置参数,作为元组处理"""
print(f"参数类型: {type(args)}") # <class 'tuple'>
return sum(args)
print(sum_numbers(1, 2, 3)) # 输出: 6
print(sum_numbers(1, 2, 3, 4, 5)) # 输出: 15
2.5 关键字可变参数 **kwargs
def print_profile(**kwargs):
"""**kwargs 接收任意数量的关键字参数,作为字典处理"""
print(f"参数类型: {type(kwargs)}") # <class 'dict'>
for key, value in kwargs.items():
print(f"{key}: {value}")
print_profile(name="Alice", age=25, city="Beijing")
# 输出:
# name: Alice
# age: 25
# city: Beijing
2.6 参数组合使用
def complex_function(a, b, *args, c=10, d=20, **kwargs):
"""完整的参数顺序:位置参数 -> *args -> 默认参数 -> **kwargs"""
print(f"a: {a}, b: {b}")
print(f"args: {args}")
print(f"c: {c}, d: {d}")
print(f"kwargs: {kwargs}")
complex_function(1, 2, 3, 4, c=30, name="Alice", age=25)
# 输出:
# a: 1, b: 2
# args: (3, 4)
# c: 30, d: 20
# kwargs: {'name': 'Alice', 'age': 25}
3. 特殊参数类型(Python 3.8+)
3.1 仅位置参数
def position_only(a, b, /, c):
"""/ 前的参数只能按位置传递"""
return a + b + c
print(position_only(1, 2, 3)) # 正确
print(position_only(1, 2, c=3)) # 正确
# position_only(a=1, b=2, c=3) # 错误:a, b不能使用关键字
3.2 仅关键字参数
def keyword_only(a, b, *, c, d):
"""* 后的参数只能按关键字传递"""
return a + b + c + d
print(keyword_only(1, 2, c=3, d=4)) # 正确
# keyword_only(1, 2, 3, 4) # 错误:c, d必须使用关键字
3.3 混合使用
def comprehensive(a, b, /, c, d, *, e, f):
"""位置参数 / 普通参数 * 关键字参数"""
return a + b + c + d + e + f
print(comprehensive(1, 2, 3, d=4, e=5, f=6)) # 正确
4. 函数注解(Type Hints)
def annotated_function(
name: str,
age: int,
*scores: float,
city: str = "Beijing",
**kwargs: str
) -> str:
"""
函数注解:提供类型提示,不影响运行时
"""
avg_score = sum(scores) / len(scores) if scores else 0
return f"{name}, {age}, from {city}, average score: {avg_score:.2f}"
# 使用示例
result = annotated_function("Alice", 25, 85.5, 92.0, 78.5, city="Shanghai", major="CS")
print(result)
5. 返回值详解
多返回值
def analyze_numbers(numbers):
"""返回多个值(实际上是返回元组)"""
if not numbers:
return 0, 0, 0
total = sum(numbers)
average = total / len(numbers)
maximum = max(numbers)
return total, average, maximum # 返回元组
# 接收多个返回值
total, avg, max_val = analyze_numbers([1, 2, 3, 4, 5])
print(f"总和: {total}, 平均: {avg}, 最大值: {max_val}")
返回函数(闭包)
def multiplier(factor):
"""返回一个函数(闭包)"""
def multiply(x):
return x * factor
return multiply
double = multiplier(2)
triple = multiplier(3)
print(double(5)) # 输出: 10
print(triple(5)) # 输出: 15
6. 高级函数特性
6.1 递归函数
def factorial(n):
"""递归计算阶乘"""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 输出: 120
6.2 生成器函数
def fibonacci_sequence(limit):
"""生成器函数:生成斐波那契数列"""
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
# 使用生成器
for num in fibonacci_sequence(100):
print(num, end=" ")
# 输出: 0 1 1 2 3 5 8 13 21 34 55 89
6.3 装饰器函数
def timer_decorator(func):
"""计时装饰器"""
def wrapper(*args, **kwargs):
import time
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"函数 {func.__name__} 执行时间: {end - start:.4f}秒")
return result
return wrapper
@timer_decorator
def slow_function():
"""被装饰的函数"""
import time
time.sleep(1)
return "完成"
print(slow_function())
7. 作用域规则
global_var = "全局变量"
def scope_demo():
local_var = "局部变量"
print(f"函数内访问全局变量: {global_var}")
print(f"函数内访问局部变量: {local_var}")
def inner_function():
inner_var = "内部变量"
nonlocal local_var # 修改外部函数的变量
local_var = "修改后的局部变量"
print(f"内部函数访问: {local_var}")
inner_function()
print(f"外部函数看到: {local_var}")
scope_demo()
8. 最佳实践总结
命名规范:使用小写字母和下划线,动词开头
单一职责:一个函数只做一件事
文档字符串:为复杂函数添加文档
参数设计:合理使用默认参数和类型提示
错误处理:在函数内处理可能的异常
保持简洁:函数体不宜过长
def calculate_grade(scores: list[float]) -> dict[str, float]:
"""
计算学生成绩统计信息
Args:
scores: 分数列表
Returns:
包含各种统计信息的字典
"""
if not scores:
raise ValueError("分数列表不能为空")
return {
'average': sum(scores) / len(scores),
'max': max(scores),
'min': min(scores),
'count': len(scores)
}
# 使用示例
try:
result = calculate_grade([85, 92, 78, 96, 88])
print(result)
except ValueError as e:
print(f"错误: {e}")
9. 使用建议
使用def的情况:
复杂逻辑或多行代码
需要重复使用的函数
需要文档字符串和类型注解的函数
使用lambda的情况:
简单的单行操作
作为参数传递给高阶函数
临时使用的回调函数
代码可读性优先:
# 好的实践
numbers = [1, 2, 3, 4, 5]
# 清晰易懂的lambda
doubled = list(map(lambda x: x * 2, numbers))
# 如果逻辑复杂,使用def
def complex_calculation(x):
"""执行复杂计算"""
# 多行逻辑...
return result
通过合理使用def和lambda,可读性通常比简洁性更重要!
更多推荐
所有评论(0)