Appearance
函数
函数是组织好的、可重复使用的代码块,用于实现特定功能。Python 提供了灵活的函数定义方式。
函数定义
基本语法
python
# 定义函数
def greet():
"""问候函数"""
print("Hello, Python!")
# 调用函数
greet()
# 带参数的函数
def greet_person(name):
"""问候指定的人"""
print(f"Hello, {name}!")
greet_person("张三")
# 带返回值的函数
def add(a, b):
"""两数相加"""
return a + b
result = add(10, 20)
print(f"结果:{result}")
# 多个返回值
def get_info():
"""返回多个值"""
name = "张三"
age = 25
return name, age
n, a = get_info()
print(f"姓名:{n},年龄:{a}")文档字符串
python
def calculate_area(width, height):
"""
计算矩形面积
参数:
width: 矩形的宽度
height: 矩形的高度
返回:
矩形的面积
示例:
>>> calculate_area(5, 3)
15
"""
return width * height
# 访问文档字符串
print(calculate_area.__doc__)
# 使用 help() 查看帮助
# help(calculate_area)参数类型
位置参数
python
# 位置参数:按顺序传递
def power(base, exp):
"""计算 base 的 exp 次方"""
return base ** exp
print(power(2, 3)) # 8
# 必须传递所有位置参数
# power(2) # TypeError默认参数
python
# 默认参数:有默认值的参数
def greet(name, greeting="Hello"):
"""带默认值的问候"""
print(f"{greeting}, {name}!")
greet("张三") # Hello, 张三!
greet("李四", "Hi") # Hi, 李四!
# 默认参数必须在位置参数之后
# def greet(greeting="Hello", name): # 语法错误
# pass
# 默认参数的陷阱(可变对象)
def add_item(item, items=[]): # 危险!
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'](不是预期的结果)
# 正确做法
def add_item_safe(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item_safe("a")) # ['a']
print(add_item_safe("b")) # ['b']关键字参数
python
# 关键字参数:通过参数名传递
def create_profile(name, age, city):
"""创建个人信息"""
return {"name": name, "age": age, "city": city}
# 使用关键字参数(顺序可以改变)
profile1 = create_profile(name="张三", age=25, city="北京")
profile2 = create_profile(age=30, city="上海", name="李四")
profile3 = create_profile("王五", city="广州", age=28) # 混合使用
print(profile1)
print(profile2)
print(profile3)可变参数
python
# *args:接收任意数量的位置参数(元组)
def sum_all(*args):
"""计算所有参数的和"""
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
print(sum_all()) # 0
# **kwargs:接收任意数量的关键字参数(字典)
def print_info(**kwargs):
"""打印所有关键字参数"""
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="张三", age=25, city="北京")
# 混合使用
def func(a, b, *args, **kwargs):
print(f"a={a}, b={b}")
print(f"args={args}")
print(f"kwargs={kwargs}")
func(1, 2, 3, 4, x=5, y=6)
# a=1, b=2
# args=(3, 4)
# kwargs={'x': 5, 'y': 6}
# 解包传递
numbers = [1, 2, 3, 4, 5]
print(sum_all(*numbers)) # 解包列表
info = {"name": "李四", "age": 30}
print_info(**info) # 解包字典仅限关键字参数
python
# * 后面的参数必须使用关键字传递
def greet(name, *, greeting="Hello"):
"""greeting 必须使用关键字传递"""
print(f"{greeting}, {name}!")
greet("张三", greeting="Hi") # 正确
# greet("张三", "Hi") # 错误
# / 前面的参数必须使用位置传递(Python 3.8+)
def greet_new(name, /, greeting="Hello"):
"""name 必须使用位置传递"""
print(f"{greeting}, {name}!")
greet_new("张三") # 正确
# greet_new(name="张三") # 错误作用域
变量作用域
python
# 局部变量
def my_function():
local_var = 10 # 局部变量
print(local_var)
my_function()
# print(local_var) # NameError
# 全局变量
global_var = 100
def access_global():
print(global_var) # 可以访问
access_global()
# 修改全局变量需要使用 global
def modify_global():
global global_var
global_var = 200
modify_global()
print(global_var) # 200
# 嵌套函数的作用域
def outer():
x = 10
def inner():
nonlocal x # 引用外层函数的变量
x = 20
inner()
print(x) # 20
outer()作用域规则(LEGB)
python
# LEGB 规则:查找顺序
# Local → Enclosing → Global → Built-in
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # local
inner()
print(x) # enclosing
outer()
print(x) # global
# 内置作用域
print(len([1, 2, 3])) # 使用内置函数 len
# 不要覆盖内置函数
# len = 100 # 危险!
# print(len([1, 2, 3])) # TypeError高阶函数
函数作为参数
python
# 函数作为参数传递
def apply_operation(x, y, operation):
"""对 x 和 y 应用指定操作"""
return operation(x, y)
def add(a, b):
return a + b
def multiply(a, b):
return a * b
print(apply_operation(5, 3, add)) # 8
print(apply_operation(5, 3, multiply)) # 15
# 使用内置函数
numbers = [1, 2, 3, 4, 5]
print(list(map(str, numbers))) # ['1', '2', '3', '4', '5']
print(list(filter(lambda x: x > 2, numbers))) # [3, 4, 5]函数作为返回值
python
# 返回函数
def get_multiplier(factor):
"""返回一个乘法函数"""
def multiplier(x):
return x * factor
return multiplier
double = get_multiplier(2)
triple = get_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# 闭包:函数和其引用的环境变量
def make_counter():
"""创建计数器"""
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter1 = make_counter()
print(counter1()) # 1
print(counter1()) # 2
counter2 = make_counter()
print(counter2()) # 1(独立的计数器)Lambda 表达式
基本语法
python
# lambda 参数: 表达式
# 匿名函数,只能有一个表达式
# 简单示例
add = lambda a, b: a + b
print(add(3, 5)) # 8
square = lambda x: x ** 2
print(square(5)) # 25
# 条件表达式
is_even = lambda x: "偶数" if x % 2 == 0 else "奇数"
print(is_even(4)) # 偶数常见应用
python
# 排序
students = [
{"name": "张三", "age": 25},
{"name": "李四", "age": 20},
{"name": "王五", "age": 30}
]
# 按年龄排序
sorted_students = sorted(students, key=lambda s: s["age"])
print(sorted_students)
# 按姓名排序
sorted_by_name = sorted(students, key=lambda s: s["name"])
print(sorted_by_name)
# 过滤
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# 映射
squares = list(map(lambda x: x ** 2, numbers))
print(squares)
# reduce
from functools import reduce
total = reduce(lambda a, b: a + b, numbers)
print(total) # 55装饰器
基本概念
python
# 装饰器:修改或增强函数功能的函数
def my_decorator(func):
"""装饰器函数"""
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
# 使用装饰器
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后带参数的装饰器
python
def my_decorator(func):
"""处理任意参数的装饰器"""
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__}")
result = func(*args, **kwargs)
print(f"返回 {result}")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
result = add(3, 5)
# 调用 add
# 返回 8常用装饰器示例
python
import time
from functools import wraps
# 计时装饰器
def timer(func):
"""计算函数执行时间"""
@wraps(func) # 保留原函数的元信息
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行时间:{end - start:.4f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "完成"
slow_function()
# 日志装饰器
def logger(func):
"""记录函数调用"""
@wraps(func)
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__},参数:{args}, {kwargs}")
result = func(*args, **kwargs)
print(f"返回:{result}")
return result
return wrapper
@logger
def greet(name):
return f"Hello, {name}!"
greet("张三")类装饰器
python
# 使用类作为装饰器
class CountCalls:
"""统计函数调用次数"""
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"第 {self.count} 次调用 {self.func.__name__}")
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello!")
say_hello()
say_hello()
say_hello()递归
递归函数
python
# 递归:函数调用自身
# 计算阶乘
def factorial(n):
"""计算 n 的阶乘"""
if n <= 1:
return 1
return n * factorial(n - 1)
print(f"5! = {factorial(5)}") # 120
# 斐波那契数列
def fibonacci(n):
"""第 n 个斐波那契数"""
if n <= 2:
return 1
return fibonacci(n - 1) + fibonacci(n - 2)
# 打印前 10 个斐波那契数
print([fibonacci(i) for i in range(1, 11)])
# 汉诺塔
def hanoi(n, source, auxiliary, target):
"""汉诺塔问题"""
if n == 1:
print(f"移动盘子 1 从 {source} 到 {target}")
return
hanoi(n - 1, source, target, auxiliary)
print(f"移动盘子 {n} 从 {source} 到 {target}")
hanoi(n - 1, auxiliary, source, target)
hanoi(3, "A", "B", "C")
# 递归深度限制
import sys
print(f"默认递归深度:{sys.getrecursionlimit()}")
# sys.setrecursionlimit(2000) # 可以修改小结
本章我们学习了:
- 函数定义:def、return、文档字符串
- 参数类型:位置参数、默认参数、关键字参数、可变参数
- 作用域:局部变量、全局变量、LEGB 规则
- 高阶函数:函数作为参数和返回值
- Lambda 表达式:匿名函数
- 装饰器:修改或增强函数功能
- 递归:函数调用自身
下一章,我们将学习 列表与元组,了解 Python 中重要的数据结构。
