2.Python 函数详解教程
引言
函数是 Python 编程的核心概念之一,它允许我们将代码组织成可重用的块。掌握函数的使用,能够让你的代码更加模块化、可维护和高效。本教程将系统地讲解 Python 函数的各个方面,每个概念都配有可直接运行的代码示例。
学习建议:
- 阅读每个示例代码
- 复制代码到 Python 解释器或 IDE 中运行
- 尝试修改代码,观察结果变化
- 完成每个部分的练习
第一部分:函数基础
1. 什么是函数
函数是一段可重用的代码块,用于执行特定的任务。使用函数可以:
- 代码复用:避免重复编写相同的代码
- 模块化:将复杂问题分解为小问题
- 易于维护:修改功能时只需修改函数定义
2. 定义和调用函数
基本语法:
def function_name(parameters):
"""函数文档字符串(可选)"""
# 函数体
return value # 返回值(可选)
示例 1:最简单的函数
# 定义一个简单的函数
def greet():
print("Hello, Python!")
# 调用函数
greet() # 输出:Hello, Python!
greet() # 可以多次调用
greet() # 输出:Hello, Python!
运行测试:
# 复制以下代码到 Python 解释器运行
def say_hello():
print("你好,世界!")
say_hello()
say_hello()
say_hello()
示例 2:带参数的函数
# 定义带参数的函数
def greet(name):
print(f"Hello, {name}!")
# 调用函数并传入参数
greet("Alice") # 输出:Hello, Alice!
greet("Bob") # 输出:Hello, Bob!
greet("Charlie") # 输出:Hello, Charlie!
运行测试:
# 复制以下代码到 Python 解释器运行
def introduce(name, age):
print(f"我的名字是 {name},今年 {age} 岁。")
introduce("张三", 25)
introduce("李四", 30)
3. 返回值
函数可以使用 return 语句返回一个值。如果没有 return 语句,函数默认返回 None。
示例 1:返回单个值
# 定义返回值的函数
def add(a, b):
result = a + b
return result
# 调用函数并使用返回值
sum_result = add(3, 5)
print(sum_result) # 输出:8
# 直接在表达式中使用
print(add(10, 20)) # 输出:30
print(add(7, 3) * 2) # 输出:20
运行测试:
# 复制以下代码到 Python 解释器运行
def multiply(x, y):
return x * y
result = multiply(6, 7)
print(f"6 × 7 = {result}") # 输出:6 × 7 = 42
# 链式调用
print(multiply(2, multiply(3, 4))) # 输出:24
示例 2:返回多个值(元组)
# Python 函数可以返回多个值(实际上是返回一个元组)
def get_name_and_age():
name = "Alice"
age = 25
return name, age # 返回元组
# 接收返回值
person_name, person_age = get_name_and_age()
print(f"姓名:{person_name},年龄:{person_age}") # 输出:姓名:Alice,年龄:25
# 或者接收整个元组
info = get_name_and_age()
print(info) # 输出:('Alice', 25)
print(type(info)) # 输出:<class 'tuple'>
运行测试:
# 复制以下代码到 Python 解释器运行
def calculate(x, y):
sum_result = x + y
product = x * y
difference = x - y
return sum_result, product, difference
a, b, c = calculate(10, 3)
print(f"和:{a},积:{b},差:{c}") # 输出:和:13,积:30,差:7
示例 3:提前返回
# 函数可以使用多个 return 语句
def check_positive(number):
if number > 0:
return "正数"
elif number < 0:
return "负数"
else:
return "零"
print(check_positive(5)) # 输出:正数
print(check_positive(-3)) # 输出:负数
print(check_positive(0)) # 输出:零
运行测试:
# 复制以下代码到 Python 解释器运行
def is_even(num):
if num % 2 == 0:
return True
return False
print(is_even(4)) # 输出:True
print(is_even(7)) # 输出:False
第二部分:函数参数
1. 位置参数
位置参数是按照定义顺序传递的参数。
def introduce(name, age, city):
print(f"我是 {name},{age} 岁,来自 {city}。")
# 必须按照顺序传递参数
introduce("张三", 25, "北京") # 输出:我是 张三,25 岁,来自 北京。
introduce("李四", 30, "上海") # 输出:我是 李四,30 岁,来自 上海。
# 错误示例:参数顺序错误
# introduce(25, "张三", "北京") # 这会导致错误或意外结果
运行测试:
# 复制以下代码到 Python 解释器运行
def calculate_area(length, width):
area = length * width
return area
print(f"矩形面积:{calculate_area(5, 3)}") # 输出:矩形面积:15
2. 关键字参数
使用参数名来传递参数,可以不按顺序。
def introduce(name, age, city):
print(f"我是 {name},{age} 岁,来自 {city}。")
# 使用关键字参数,可以不按顺序
introduce(age=25, name="张三", city="北京") # 输出:我是 张三,25 岁,来自 北京。
introduce(city="上海", name="李四", age=30) # 输出:我是 李四,30 岁,来自 上海。
# 混合使用位置参数和关键字参数
introduce("王五", age=28, city="广州") # 位置参数必须在关键字参数之前
运行测试:
# 复制以下代码到 Python 解释器运行
def create_profile(name, email, age, city):
print(f"姓名:{name}")
print(f"邮箱:{email}")
print(f"年龄:{age}")
print(f"城市:{city}")
# 使用关键字参数
create_profile(email="test@example.com", name="测试用户", city="深圳", age=22)
3. 默认参数
可以为参数设置默认值,调用时可以不传递这些参数。
# 定义带默认参数的函数
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
# 使用默认值
greet("Alice") # 输出:Hello, Alice!
# 覆盖默认值
greet("Bob", "Hi") # 输出:Hi, Bob!
greet("Charlie", greeting="Good morning") # 输出:Good morning, Charlie!
运行测试:
# 复制以下代码到 Python 解释器运行
def power(base, exponent=2):
"""计算 base 的 exponent 次方"""
return base ** exponent
print(power(3)) # 输出:9(使用默认值 exponent=2)
print(power(3, 3)) # 输出:27
print(power(2, 10)) # 输出:1024
重要提示:默认参数的值在函数定义时计算一次
# 注意:默认参数如果是可变对象(如列表、字典),要特别小心
def add_item(item, my_list=[]): # 不推荐这样做
my_list.append(item)
return my_list
# 这会导致意外的结果
print(add_item("apple")) # 输出:['apple']
print(add_item("banana")) # 输出:['apple', 'banana'](意外!)
# 正确的做法:使用 None 作为默认值
def add_item_correct(item, my_list=None):
if my_list is None:
my_list = []
my_list.append(item)
return my_list
print(add_item_correct("apple")) # 输出:['apple']
print(add_item_correct("banana")) # 输出:['banana'](正确!)
运行测试:
# 复制以下代码到 Python 解释器运行
# 测试默认参数陷阱
def bad_function(x, items=[]):
items.append(x)
return items
def good_function(x, items=None):
if items is None:
items = []
items.append(x)
return items
print("错误示例:")
print(bad_function(1)) # 输出:[1]
print(bad_function(2)) # 输出:[1, 2](意外!)
print("\n正确示例:")
print(good_function(1)) # 输出:[1]
print(good_function(2)) # 输出:[2](正确!)
4. 可变位置参数(*args)
使用 *args 可以接收任意数量的位置参数。
# *args 接收任意数量的位置参数,打包成元组
def sum_all(*args):
print(f"接收到的参数:{args}")
print(f"参数类型:{type(args)}")
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 输出:接收到的参数:(1, 2, 3),总和:6
print(sum_all(1, 2, 3, 4, 5)) # 输出:接收到的参数:(1, 2, 3, 4, 5),总和:15
print(sum_all(10)) # 输出:接收到的参数:(10,),总和:10
print(sum_all()) # 输出:接收到的参数:(),总和:0
运行测试:
# 复制以下代码到 Python 解释器运行
def print_info(*args):
print(f"共接收到 {len(args)} 个参数:")
for i, arg in enumerate(args, 1):
print(f" 参数 {i}:{arg}")
print_info("苹果", "香蕉", "橙子")
print_info(1, 2, 3, 4, 5)
*混合使用位置参数和 args:
def introduce(name, *hobbies):
print(f"我是 {name},我的爱好有:")
for hobby in hobbies:
print(f" - {hobby}")
introduce("张三", "读书", "游泳", "编程")
# 输出:
# 我是 张三,我的爱好有:
# - 读书
# - 游泳
# - 编程
运行测试:
# 复制以下代码到 Python 解释器运行
def calculate_average(first, *rest):
"""计算平均值,第一个参数单独处理"""
total = first + sum(rest)
count = 1 + len(rest)
return total / count
print(calculate_average(10, 20, 30)) # 输出:20.0
print(calculate_average(5, 10, 15, 20)) # 输出:12.5
5. 可变关键字参数(**kwargs)
使用 **kwargs 可以接收任意数量的关键字参数。
# **kwargs 接收任意数量的关键字参数,打包成字典
def print_info(**kwargs):
print(f"接收到的关键字参数:{kwargs}")
print(f"参数类型:{type(kwargs)}")
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="Beijing")
# 输出:
# 接收到的关键字参数:{'name': 'Alice', 'age': 25, 'city': 'Beijing'}
# 参数类型:<class 'dict'>
# name: Alice
# age: 25
# city: Beijing
print_info(title="Python", version=3.11)
# 输出:
# 接收到的关键字参数:{'title': 'Python', 'version': 3.11}
# title: Python
# version: 3.11
运行测试:
# 复制以下代码到 Python 解释器运行
def create_user(**kwargs):
print("创建用户:")
for key, value in kwargs.items():
print(f" {key}: {value}")
create_user(username="testuser", email="test@example.com", age=25)
混合使用所有参数类型:
# 参数顺序:位置参数 -> *args -> 关键字参数 -> **kwargs
def complex_function(required, *args, default="默认值", **kwargs):
print(f"必需参数:{required}")
print(f"可变位置参数:{args}")
print(f"默认参数:{default}")
print(f"可变关键字参数:{kwargs}")
complex_function("必需", 1, 2, 3, default="自定义", key1="value1", key2="value2")
# 输出:
# 必需参数:必需
# 可变位置参数:(1, 2, 3)
# 默认参数:自定义
# 可变关键字参数:{'key1': 'value1', 'key2': 'value2'}
运行测试:
# 复制以下代码到 Python 解释器运行
def flexible_function(name, *scores, subject="数学", **info):
print(f"学生:{name}")
print(f"科目:{subject}")
print(f"成绩:{scores}")
print(f"其他信息:{info}")
flexible_function("小明", 85, 90, 88, subject="语文", class_name="三年级", teacher="李老师")
第三部分:函数文档字符串
文档字符串(docstring)用于描述函数的功能、参数和返回值。
def calculate_area(length, width):
"""
计算矩形的面积
参数:
length (float): 矩形的长度
width (float): 矩形的宽度
返回:
float: 矩形的面积
"""
return length * width
# 查看文档字符串
print(calculate_area.__doc__)
help(calculate_area)
运行测试:
# 复制以下代码到 Python 解释器运行
def factorial(n):
"""
计算阶乘
参数:
n (int): 非负整数
返回:
int: n 的阶乘
示例:
>>> factorial(5)
120
"""
if n <= 1:
return 1
return n * factorial(n - 1)
# 查看文档
print(factorial.__doc__)
print(f"5! = {factorial(5)}")
第四部分:Lambda 函数(匿名函数)
Lambda 函数是一种简洁的函数定义方式,适用于简单的函数。
基本语法:
lambda arguments: expression
示例:
# 普通函数定义
def add(x, y):
return x + y
# Lambda 函数等价写法
add_lambda = lambda x, y: x + y
print(add(3, 5)) # 输出:8
print(add_lambda(3, 5)) # 输出:8
运行测试:
# 复制以下代码到 Python 解释器运行
# Lambda 函数常用于需要函数作为参数的场景
numbers = [1, 2, 3, 4, 5]
# 使用 lambda 函数进行映射
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # 输出:[1, 4, 9, 16, 25]
# 使用 lambda 函数进行过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # 输出:[2, 4]
# 使用 lambda 函数进行排序
pairs = [(1, 3), (2, 1), (3, 2)]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs) # 输出:[(2, 1), (3, 2), (1, 3)]
更多 Lambda 示例:
# Lambda 函数示例集合
# 1. 单参数
square = lambda x: x ** 2
print(square(5)) # 输出:25
# 2. 无参数
get_pi = lambda: 3.14159
print(get_pi()) # 输出:3.14159
# 3. 多参数
multiply = lambda x, y, z: x * y * z
print(multiply(2, 3, 4)) # 输出:24
# 4. 条件表达式
max_value = lambda a, b: a if a > b else b
print(max_value(10, 20)) # 输出:20
运行测试:
# 复制以下代码到 Python 解释器运行
# 使用 lambda 函数处理列表
data = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 20}
]
# 按年龄排序
sorted_by_age = sorted(data, key=lambda x: x["age"])
for person in sorted_by_age:
print(f"{person['name']}: {person['age']} 岁")
第五部分:变量作用域
1. 局部变量和全局变量
# 全局变量
global_var = "我是全局变量"
def test_scope():
# 局部变量
local_var = "我是局部变量"
print(f"函数内部 - 全局变量:{global_var}")
print(f"函数内部 - 局部变量:{local_var}")
test_scope()
print(f"函数外部 - 全局变量:{global_var}")
# print(local_var) # 错误!局部变量在函数外部不可访问
运行测试:
# 复制以下代码到 Python 解释器运行
x = 10 # 全局变量
def modify_x():
x = 20 # 创建局部变量,不影响全局变量
print(f"函数内部 x = {x}")
modify_x()
print(f"函数外部 x = {x}") # 输出:函数外部 x = 10
2. global 关键字
使用 global 关键字可以在函数内部修改全局变量。
count = 0 # 全局变量
def increment():
global count # 声明使用全局变量
count += 1
print(f"计数:{count}")
increment() # 输出:计数:1
increment() # 输出:计数:2
increment() # 输出:计数:3
print(f"最终计数:{count}") # 输出:最终计数:3
运行测试:
# 复制以下代码到 Python 解释器运行
balance = 1000 # 全局变量:账户余额
def deposit(amount):
global balance
balance += amount
print(f"存入 {amount},当前余额:{balance}")
def withdraw(amount):
global balance
if amount <= balance:
balance -= amount
print(f"取出 {amount},当前余额:{balance}")
else:
print("余额不足!")
deposit(500)
withdraw(300)
withdraw(1500) # 余额不足
3. nonlocal 关键字
nonlocal 用于在嵌套函数中修改外层函数的变量。
def outer():
x = "外层变量"
def inner():
nonlocal x # 声明使用外层函数的变量
x = "修改后的外层变量"
print(f"内部函数:{x}")
print(f"调用 inner 前:{x}")
inner()
print(f"调用 inner 后:{x}")
outer()
# 输出:
# 调用 inner 前:外层变量
# 内部函数:修改后的外层变量
# 调用 inner 后:修改后的外层变量
运行测试:
# 复制以下代码到 Python 解释器运行
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
# 创建计数器
counter1 = counter()
print(counter1()) # 输出:1
print(counter1()) # 输出:2
print(counter1()) # 输出:3
# 创建另一个独立的计数器
counter2 = counter()
print(counter2()) # 输出:1(独立的计数器)
第六部分:闭包
闭包是指内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。
def outer_function(x):
# 外部函数的变量
outer_var = x
def inner_function(y):
# 内部函数可以访问外部函数的变量
return outer_var + y
# 返回内部函数(注意:没有调用,只是返回函数对象)
return inner_function
# 创建闭包
closure = outer_function(10)
print(closure(5)) # 输出:15
print(closure(20)) # 输出:30
运行测试:
# 复制以下代码到 Python 解释器运行
def multiplier(factor):
"""创建一个乘法器函数"""
def multiply(number):
return number * factor
return multiply
# 创建不同的乘法器
double = multiplier(2)
triple = multiplier(3)
print(double(5)) # 输出:10
print(triple(5)) # 输出:15
print(double(10)) # 输出:20
实用的闭包示例:
def create_validator(min_value, max_value):
"""创建一个数值验证器"""
def validate(value):
if min_value <= value <= max_value:
return True, f"值 {value} 在有效范围内"
else:
return False, f"值 {value} 超出范围 [{min_value}, {max_value}]"
return validate
# 创建年龄验证器(0-150)
age_validator = create_validator(0, 150)
print(age_validator(25)) # 输出:(True, '值 25 在有效范围内')
print(age_validator(200)) # 输出:(False, '值 200 超出范围 [0, 150]')
# 创建分数验证器(0-100)
score_validator = create_validator(0, 100)
print(score_validator(85)) # 输出:(True, '值 85 在有效范围内')
print(score_validator(150)) # 输出:(False, '值 150 超出范围 [0, 100]')
运行测试:
# 复制以下代码到 Python 解释器运行
def power_factory(exponent):
"""创建幂函数工厂"""
def power(base):
return base ** exponent
return power
# 创建不同的幂函数
square = power_factory(2)
cube = power_factory(3)
print(square(4)) # 输出:16 (4^2)
print(cube(4)) # 输出:64 (4^3)
第七部分:递归函数
递归函数是调用自身的函数。递归是解决某些问题的优雅方法。
基本结构:
def recursive_function(parameters):
# 基本情况(终止条件)
if base_case:
return base_value
# 递归情况
return recursive_function(modified_parameters)
示例 1:计算阶乘
def factorial(n):
"""
计算 n 的阶乘
5! = 5 × 4 × 3 × 2 × 1 = 120
"""
# 基本情况
if n <= 1:
return 1
# 递归情况
return n * factorial(n - 1)
print(factorial(5)) # 输出:120
print(factorial(3)) # 输出:6
print(factorial(0)) # 输出:1
运行测试:
# 复制以下代码到 Python 解释器运行
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
# 测试
for i in range(6):
print(f"{i}! = {factorial(i)}")
示例 2:斐波那契数列
def fibonacci(n):
"""
计算斐波那契数列的第 n 项
0, 1, 1, 2, 3, 5, 8, 13, 21, ...
"""
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
# 生成前 10 个斐波那契数
for i in range(10):
print(f"F({i}) = {fibonacci(i)}")
运行测试:
# 复制以下代码到 Python 解释器运行
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
# 打印前 10 个斐波那契数
print("斐波那契数列:")
for i in range(10):
print(f"F({i}) = {fibonacci(i)}")
示例 3:计算列表元素之和
def sum_list(numbers):
"""递归计算列表元素之和"""
if len(numbers) == 0:
return 0
else:
return numbers[0] + sum_list(numbers[1:])
print(sum_list([1, 2, 3, 4, 5])) # 输出:15
print(sum_list([10, 20, 30])) # 输出:60
运行测试:
# 复制以下代码到 Python 解释器运行
def sum_list(numbers):
if not numbers:
return 0
return numbers[0] + sum_list(numbers[1:])
test_lists = [
[1, 2, 3],
[10, 20, 30, 40],
[5],
[]
]
for lst in test_lists:
print(f"sum_list({lst}) = {sum_list(lst)}")
递归的注意事项:
- 必须有终止条件(基本情况)
- 递归调用必须向基本情况靠近
- Python 默认递归深度限制为 1000(可通过
sys.setrecursionlimit()修改)
第八部分:装饰器
装饰器是 Python 的高级特性,允许在不修改原函数的情况下增强函数功能。
1. 函数作为对象
在 Python 中,函数是一等对象,可以作为参数传递、赋值给变量等。
def greet(name):
return f"Hello, {name}!"
# 函数可以作为变量
say_hello = greet
print(say_hello("Alice")) # 输出:Hello, Alice!
# 函数可以作为参数
def call_function(func, arg):
return func(arg)
print(call_function(greet, "Bob")) # 输出:Hello, Bob!
运行测试:
# 复制以下代码到 Python 解释器运行
def add(x, y):
return x + y
def multiply(x, y):
return x * y
def calculate(func, a, b):
return func(a, b)
print(calculate(add, 5, 3)) # 输出:8
print(calculate(multiply, 5, 3)) # 输出:15
2. 简单装饰器
def my_decorator(func):
def wrapper():
print("装饰器:函数执行前")
result = func()
print("装饰器:函数执行后")
return result
return wrapper
@my_decorator
def say_hello():
print("Hello, World!")
say_hello()
# 输出:
# 装饰器:函数执行前
# Hello, World!
# 装饰器:函数执行后
运行测试:
# 复制以下代码到 Python 解释器运行
def timer_decorator(func):
import time
def wrapper():
start = time.time()
result = func()
end = time.time()
print(f"函数执行时间:{end - start:.4f} 秒")
return result
return wrapper
@timer_decorator
def slow_function():
import time
time.sleep(1)
return "完成"
slow_function()
3. 带参数的装饰器
def repeat(times):
"""装饰器工厂:创建重复执行函数的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(times):
print(f"第 {i + 1} 次执行:")
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(times=3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# 输出:
# 第 1 次执行:
# Hello, Alice!
# 第 2 次执行:
# Hello, Alice!
# 第 3 次执行:
# Hello, Alice!
运行测试:
# 复制以下代码到 Python 解释器运行
def log_calls(func):
"""记录函数调用的装饰器"""
def wrapper(*args, **kwargs):
print(f"调用函数:{func.__name__}")
print(f"参数:args={args}, kwargs={kwargs}")
result = func(*args, **kwargs)
print(f"返回值:{result}")
return result
return wrapper
@log_calls
def add(x, y):
return x + y
@log_calls
def multiply(x, y):
return x * y
add(3, 5)
multiply(4, 6)
4. 使用 functools.wraps 保留函数元信息
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留原函数的元信息
def wrapper(*args, **kwargs):
print(f"调用函数:{func.__name__}")
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""这是一个示例函数"""
pass
print(example.__name__) # 输出:example(而不是 wrapper)
print(example.__doc__) # 输出:这是一个示例函数
运行测试:
# 复制以下代码到 Python 解释器运行
from functools import wraps
def count_calls(func):
"""统计函数调用次数的装饰器"""
@wraps(func)
def wrapper(*args, **kwargs):
wrapper.call_count += 1
print(f"{func.__name__} 被调用了 {wrapper.call_count} 次")
return func(*args, **kwargs)
wrapper.call_count = 0
return wrapper
@count_calls
def greet(name):
return f"Hello, {name}!"
greet("Alice")
greet("Bob")
greet("Charlie")
print(f"函数名:{greet.__name__}") # 输出:greet
第九部分:内置函数和常用函数
1. 常用内置函数
# 1. len() - 获取长度
print(len("Hello")) # 输出:5
print(len([1, 2, 3, 4])) # 输出:4
# 2. type() - 获取类型
print(type(5)) # 输出:<class 'int'>
print(type("hello")) # 输出:<class 'str'>
# 3. isinstance() - 类型检查
print(isinstance(5, int)) # 输出:True
print(isinstance("hello", int)) # 输出:False
# 4. range() - 生成数字序列
print(list(range(5))) # 输出:[0, 1, 2, 3, 4]
print(list(range(1, 5))) # 输出:[1, 2, 3, 4]
print(list(range(1, 10, 2))) # 输出:[1, 3, 5, 7, 9]
# 5. enumerate() - 枚举
for i, value in enumerate(["a", "b", "c"]):
print(f"索引 {i}: {value}")
# 6. zip() - 组合多个序列
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name}: {age} 岁")
运行测试:
# 复制以下代码到 Python 解释器运行
# 使用内置函数处理数据
numbers = [1, 2, 3, 4, 5]
print(f"最大值:{max(numbers)}")
print(f"最小值:{min(numbers)}")
print(f"总和:{sum(numbers)}")
print(f"平均值:{sum(numbers) / len(numbers)}")
# 使用 map 和 filter
squared = list(map(lambda x: x ** 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(f"平方:{squared}")
print(f"偶数:{evens}")
2. 自定义实用函数示例
def find_max_min(numbers):
"""找到列表中的最大值和最小值"""
if not numbers:
return None, None
return max(numbers), min(numbers)
def count_words(text):
"""统计文本中的单词数"""
words = text.split()
return len(words)
def reverse_string(text):
"""反转字符串"""
return text[::-1]
# 测试
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
max_val, min_val = find_max_min(numbers)
print(f"最大值:{max_val},最小值:{min_val}")
text = "Python 是一门优秀的编程语言"
print(f"单词数:{count_words(text)}")
print(f"反转后:{reverse_string(text)}")
运行测试:
# 复制以下代码到 Python 解释器运行
def is_palindrome(text):
"""检查字符串是否为回文"""
cleaned = text.lower().replace(" ", "")
return cleaned == cleaned[::-1]
def remove_duplicates(items):
"""移除列表中的重复元素,保持顺序"""
seen = set()
result = []
for item in items:
if item not in seen:
seen.add(item)
result.append(item)
return result
# 测试
print(is_palindrome("racecar")) # 输出:True
print(is_palindrome("Python")) # 输出:False
print(remove_duplicates([1, 2, 2, 3, 3, 3, 4])) # 输出:[1, 2, 3, 4]
第十部分:函数最佳实践
1. 函数命名规范
# 好的命名:清晰、描述性
def calculate_total_price():
pass
def get_user_by_id():
pass
# 不好的命名:不清晰
def calc():
pass
def func1():
pass
2. 单一职责原则
# 好的设计:每个函数只做一件事
def validate_email(email):
"""验证邮箱格式"""
return "@" in email and "." in email.split("@")[1]
def send_email(email, message):
"""发送邮件"""
if validate_email(email):
print(f"发送邮件到 {email}: {message}")
else:
print("邮箱格式无效")
# 不好的设计:一个函数做多件事
def validate_and_send_email(email, message):
"""验证并发送邮件(违反单一职责原则)"""
if "@" in email:
print(f"发送邮件到 {email}: {message}")
3. 函数应该简短
# 好的设计:函数简短,易于理解
def calculate_discount(price, discount_rate):
"""计算折扣后的价格"""
return price * (1 - discount_rate)
def calculate_tax(price, tax_rate):
"""计算税费"""
return price * tax_rate
def calculate_final_price(price, discount_rate, tax_rate):
"""计算最终价格"""
discounted = calculate_discount(price, discount_rate)
return discounted + calculate_tax(discounted, tax_rate)
4. 使用类型提示(Python 3.5+)
def add(x: int, y: int) -> int:
"""添加两个整数"""
return x + y
def greet(name: str) -> str:
"""问候某人"""
return f"Hello, {name}!"
def process_data(data: list[str]) -> dict[str, int]:
"""处理数据列表,返回统计字典"""
return {item: len(item) for item in data}
运行测试:
# 复制以下代码到 Python 解释器运行(Python 3.5+)
from typing import List, Dict, Optional
def find_max(numbers: List[int]) -> Optional[int]:
"""找到列表中的最大值"""
if not numbers:
return None
return max(numbers)
def create_user(name: str, age: int, email: Optional[str] = None) -> Dict[str, any]:
"""创建用户字典"""
user = {"name": name, "age": age}
if email:
user["email"] = email
return user
print(find_max([1, 5, 3, 9, 2]))
print(create_user("Alice", 25, "alice@example.com"))
第十一部分:综合练习
练习 1:计算器函数
def calculator(operation, a, b):
"""
简单的计算器函数
参数:
operation (str): 操作类型('+', '-', '*', '/')
a (float): 第一个数字
b (float): 第二个数字
返回:
float: 计算结果
"""
operations = {
'+': lambda x, y: x + y,
'-': lambda x, y: x - y,
'*': lambda x, y: x * y,
'/': lambda x, y: x / y if y != 0 else None
}
func = operations.get(operation)
if func is None:
return None
return func(a, b)
# 测试
print(calculator('+', 10, 5)) # 输出:15
print(calculator('-', 10, 5)) # 输出:5
print(calculator('*', 10, 5)) # 输出:50
print(calculator('/', 10, 5)) # 输出:2.0
print(calculator('/', 10, 0)) # 输出:None
运行测试:
# 复制以下代码到 Python 解释器运行
def calculator(operation, a, b):
operations = {
'+': lambda x, y: x + y,
'-': lambda x, y: x - y,
'*': lambda x, y: x * y,
'/': lambda x, y: x / y if y != 0 else None
}
func = operations.get(operation)
return func(a, b) if func else None
# 交互式测试
print("10 + 5 =", calculator('+', 10, 5))
print("10 - 5 =", calculator('-', 10, 5))
print("10 * 5 =", calculator('*', 10, 5))
print("10 / 5 =", calculator('/', 10, 5))
练习 2:文本处理函数集合
def word_count(text):
"""统计单词数"""
return len(text.split())
def char_count(text, include_spaces=True):
"""统计字符数"""
if include_spaces:
return len(text)
return len(text.replace(" ", ""))
def reverse_words(text):
"""反转单词顺序"""
words = text.split()
return " ".join(reversed(words))
def capitalize_words(text):
"""将每个单词首字母大写"""
return " ".join(word.capitalize() for word in text.split())
# 测试
text = "python is a great programming language"
print(f"原文:{text}")
print(f"单词数:{word_count(text)}")
print(f"字符数(含空格):{char_count(text)}")
print(f"字符数(不含空格):{char_count(text, False)}")
print(f"反转单词:{reverse_words(text)}")
print(f"首字母大写:{capitalize_words(text)}")
运行测试:
# 复制以下代码到 Python 解释器运行
def analyze_text(text):
"""综合分析文本"""
return {
"长度": len(text),
"单词数": len(text.split()),
"字符数(不含空格)": len(text.replace(" ", "")),
"大写字母数": sum(1 for c in text if c.isupper()),
"小写字母数": sum(1 for c in text if c.islower()),
"数字数": sum(1 for c in text if c.isdigit())
}
result = analyze_text("Python 3.11 is Awesome!")
for key, value in result.items():
print(f"{key}:{value}")
练习 3:数据验证函数
def validate_email(email):
"""验证邮箱格式"""
if "@" not in email:
return False, "邮箱必须包含 @"
parts = email.split("@")
if len(parts) != 2:
return False, "邮箱格式不正确"
local, domain = parts
if not local or not domain:
return False, "邮箱的本地部分和域名部分不能为空"
if "." not in domain:
return False, "域名必须包含点号"
return True, "邮箱格式正确"
def validate_password(password):
"""验证密码强度"""
if len(password) < 8:
return False, "密码长度至少 8 位"
has_upper = any(c.isupper() for c in password)
has_lower = any(c.islower() for c in password)
has_digit = any(c.isdigit() for c in password)
if not (has_upper and has_lower and has_digit):
return False, "密码必须包含大写字母、小写字母和数字"
return True, "密码强度符合要求"
# 测试
emails = ["test@example.com", "invalid.email", "user@domain"]
for email in emails:
valid, message = validate_email(email)
print(f"{email}: {message}")
passwords = ["Weak", "Strong123", "VERYSTRONG123"]
for pwd in passwords:
valid, message = validate_password(pwd)
print(f"'{pwd}': {message}")
运行测试:
# 复制以下代码到 Python 解释器运行
def validate_phone(phone):
"""验证手机号(简单版本)"""
# 移除空格和连字符
cleaned = phone.replace(" ", "").replace("-", "")
if not cleaned.isdigit():
return False, "手机号只能包含数字"
if len(cleaned) != 11:
return False, "手机号必须是 11 位数字"
if not cleaned.startswith("1"):
return False, "手机号必须以 1 开头"
return True, "手机号格式正确"
# 测试
test_phones = ["13812345678", "12345678901", "138-1234-5678", "abc12345678"]
for phone in test_phones:
valid, message = validate_phone(phone)
print(f"{phone}: {message}")
总结
通过本教程,我们系统地学习了 Python 函数的各个方面:
- 函数基础:定义、调用、返回值
- 参数类型:位置参数、关键字参数、默认参数、可变参数
- 文档字符串:如何编写清晰的函数文档
- Lambda 函数:匿名函数的用法
- 作用域:局部变量、全局变量、nonlocal
- 闭包:内部函数访问外部变量
- 递归:函数调用自身解决问题
- 装饰器:增强函数功能的高级特性
- 最佳实践:编写高质量函数的建议
关键要点:
- 函数是代码复用的基本单元
- 合理使用参数可以让函数更灵活
- 文档字符串帮助他人理解函数
- 递归适合解决分治问题
- 装饰器是 Python 的强大特性
下一步学习:
- 生成器函数:使用
yield创建生成器 - 类方法:在类中定义方法
- 异步函数:使用
async/await进行异步编程 - 函数式编程:map、filter、reduce 等
- 设计模式:策略模式、工厂模式等
记住:多练习、多实践,才能真正掌握 Python 函数!
参考资料
祝你学习愉快!