Python 知识详细解析:函数
·
本文全面解析 Python 函数的定义、参数、返回值、作用域及高级特性,配合丰富示例代码
目录
1. 函数基础
1.1 定义函数
使用 def 关键字定义函数,函数名后接圆括号和冒号
def greet():
"""这是一个简单的问候函数"""
print("Hello, Python!")
greet() # 输出: Hello, Python!
1.2 函数文档字符串(Docstring)
def calculate_area(length, width):
"""
计算矩形的面积
参数:
length (float): 矩形的长度
width (float): 矩形的宽度
返回:
float: 矩形的面积
"""
return length * width
# 查看文档
print(calculate_area.__doc__)
1.3 函数是对象
def say_hello():
print("Hello!")
# 函数可以赋值给变量
my_func = say_hello
my_func() # 输出: Hello!
# 函数可以存储在数据结构中
functions = [say_hello, lambda: print("Hi!")]
functions[0]() # 输出: Hello!
2. 参数详解
2.1 位置参数
def introduce(name, age):
print(f"我叫{name},今年{age}岁。")
introduce("张三", 25) # 输出: 我叫张三,今年25岁。
2.2 默认参数
def create_user(username, role="user", active=True):
print(f"用户名: {username}, 角色: {role}, 状态: {'激活' if active else '禁用'}")
create_user("admin") # 用户名: admin, 角色: user, 状态: 激活
create_user("manager", "admin") # 用户名: manager, 角色: admin, 状态: 激活
create_user("test", active=False) # 用户名: test, 角色: user, 状态: 禁用
⚠️ 警告:默认参数不要使用可变对象(如列表、字典),因为默认值在函数定义时只创建一次
# 错误示例
def add_item_wrong(item, items=[]):
items.append(item)
return items
print(add_item_wrong(1)) # [1]
print(add_item_wrong(2)) # [1, 2] ← 意外保留了之前的数据!
# 正确示例
def add_item_correct(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item_correct(1)) # [1]
print(add_item_correct(2)) # [2] ← 每次都是新的列表
2.3 关键字参数
def book_flight(origin, destination, date, class_type="经济舱"):
print(f"{origin} → {destination},日期: {date},舱位: {class_type}")
# 使用关键字参数,顺序可以打乱
book_flight(destination="北京", origin="上海", date="2024-05-01")
# 输出: 上海 → 北京,日期: 2024-05-01,舱位: 经济舱
2.4 可变参数 *args
def calculate_sum(*numbers):
"""接收任意数量的位置参数,以元组形式存储"""
total = 0
for num in numbers:
total += num
return total
print(calculate_sum(1, 2, 3)) # 6
print(calculate_sum()) # 0
print(calculate_sum(10, 20)) # 30
# 解包传递
data = [1, 2, 3, 4, 5]
print(calculate_sum(*data)) # 15
2.5 可变关键字参数 **kwargs
def build_profile(**kwargs):
"""接收任意数量的关键字参数,以字典形式存储"""
profile = {}
for key, value in kwargs.items():
profile[key] = value
return profile
user = build_profile(name="李四", age=30, city="深圳", hobby="编程")
print(user)
# 输出: {'name': '李四', 'age': 30, 'city': '深圳', 'hobby': '编程'}
# 解包传递
info = {"name": "王五", "job": "工程师"}
print(build_profile(**info, salary=15000))
# 输出: {'name': '王五', 'job': '工程师', 'salary': 15000}
2.6 参数顺序规则
def complex_function(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2, **kwargs):
"""
参数顺序:
1. 仅限位置参数 (/) 之前
2. 位置或关键字参数 (/) 和 (*) 之间
3. 仅限关键字参数 (*) 之后
4. **kwargs 最后
"""
print(f"pos1={pos1}, pos2={pos2}, pos_or_kwd={pos_or_kwd}")
print(f"kwd1={kwd1}, kwd2={kwd2}, kwargs={kwargs}")
complex_function(1, 2, 3, kwd1="a", kwd2="b", extra="c")
# pos1=1, pos2=2, pos_or_kwd=3
# kwd1=a, kwd2=b, kwargs={'extra': 'c'}
2.7 类型注解(Type Hints)
from typing import List, Dict, Optional
def process_data(items: List[int], config: Optional[Dict[str, str]] = None) -> int:
"""
items: 整数列表
config: 可选的配置字典
返回: 整数结果
"""
if config is None:
config = {}
multiplier = int(config.get("multiplier", "1"))
return sum(items) * multiplier
result = process_data([1, 2, 3], {"multiplier": "2"})
print(result) # 12
3. 返回值
3.1 返回单个值
import math
def circle_properties(radius):
area = math.pi * radius ** 2
return area
print(circle_properties(5)) # 78.53981633974483
3.2 返回多个值(元组解包)
def get_min_max(numbers):
"""同时返回最小值和最大值"""
return min(numbers), max(numbers)
minimum, maximum = get_min_max([3, 1, 4, 1, 5, 9, 2, 6])
print(f"最小值: {minimum}, 最大值: {maximum}")
# 输出: 最小值: 1, 最大值: 9
3.3 没有 return 语句
def print_message(msg):
print(msg)
# 没有 return,默认返回 None
result = print_message("测试")
print(result) # None
3.4 条件返回
def check_number(n):
if n > 0:
return "正数"
elif n < 0:
return "负数"
else:
return "零"
print(check_number(10)) # 正数
print(check_number(-5)) # 负数
print(check_number(0)) # 零
4. 变量作用域
4.1 LEGB 规则
Python 查找变量的顺序:Local → Enclosing → Global → Built-in
x = "global" # 全局变量
def outer():
x = "enclosing" # 嵌套作用域变量
def inner():
x = "local" # 局部变量
print(f"inner: {x}") # local
inner()
print(f"outer: {x}") # enclosing
outer()
print(f"global: {x}") # global
4.2 global 关键字
counter = 0
def increment():
global counter # 声明使用全局变量
counter += 1
print(f"计数器: {counter}")
increment() # 计数器: 1
increment() # 计数器: 2
print(f"最终值: {counter}") # 最终值: 2
4.3 nonlocal 关键字
def make_counter():
count = 0
def increment():
nonlocal count # 修改嵌套作用域的变量
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3
5. 匿名函数(Lambda)
5.1 基本语法
# 普通函数
def square(x):
return x ** 2
# 等价的 lambda 函数
square_lambda = lambda x: x ** 2
print(square(5)) # 25
print(square_lambda(5)) # 25
5.2 常见应用场景
# 排序
students = [("张三", 85), ("李四", 92), ("王五", 78)]
students.sort(key=lambda x: x[1], reverse=True)
print(students) # [('李四', 92), ('张三', 85), ('王五', 78)]
# map 函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# filter 函数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
# reduce 函数
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
5.3 多参数 Lambda
# 两个参数
add = lambda x, y: x + y
print(add(3, 5)) # 8
# 条件表达式
max_value = lambda a, b: a if a > b else b
print(max_value(10, 20)) # 20
6. 高阶函数
6.1 函数作为参数
def apply_operation(numbers, operation):
"""接收一个函数作为参数"""
return [operation(n) for n in numbers]
def double(x):
return x * 2
def triple(x):
return x * 3
nums = [1, 2, 3, 4]
print(apply_operation(nums, double)) # [2, 4, 6, 8]
print(apply_operation(nums, triple)) # [3, 6, 9, 12]
print(apply_operation(nums, lambda x: x ** 2)) # [1, 4, 9, 16]
6.2 函数作为返回值
def make_multiplier(factor):
"""返回一个函数"""
def multiplier(x):
return x * factor
return multiplier
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
6.3 内置高阶函数
# map - 映射
names = ["alice", "bob", "charlie"]
capitalized = list(map(str.capitalize, names))
print(capitalized) # ['Alice', 'Bob', 'Charlie']
# filter - 过滤
scores = [55, 70, 85, 90, 45, 60]
passed = list(filter(lambda x: x >= 60, scores))
print(passed) # [70, 85, 90, 60]
# sorted - 排序
words = ["banana", "pie", "Washington", "book"]
by_length = sorted(words, key=len)
print(by_length) # ['pie', 'book', 'banana', 'Washington']
7. 装饰器
7.1 简单装饰器
import time
def timer(func):
"""计算函数执行时间的装饰器"""
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - start
print(f"{func.__name__} 执行时间: {elapsed:.4f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "Done"
result = slow_function()
# 输出: slow_function 执行时间: 1.00xx秒
7.2 带参数的装饰器
def repeat(times):
"""接收参数的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(times=3)
def greet(name):
print(f"Hello, {name}!")
greet("Python")
# 输出:
# Hello, Python!
# Hello, Python!
# Hello, Python!
7.3 保留元信息的装饰器
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留原函数的元信息
def wrapper(*args, **kwargs):
print("装饰器执行前")
result = func(*args, **kwargs)
print("装饰器执行后")
return result
return wrapper
@my_decorator
def example():
"""示例函数"""
print("函数主体")
print(example.__name__) # example(不是 wrapper)
print(example.__doc__) # 示例函数
7.4 类装饰器
class CountCalls:
"""统计函数调用次数的类装饰器"""
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"第 {self.count} 次调用")
return self.func(*args, **kwargs)
@CountCalls
def say_hi():
print("Hi!")
say_hi() # 第 1 次调用
say_hi() # 第 2 次调用
say_hi() # 第 3 次调用
8. 递归函数
8.1 阶乘计算
def factorial(n):
"""计算 n 的阶乘"""
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
print(factorial(10)) # 3628800
8.2 斐波那契数列
def fibonacci(n):
"""返回第 n 个斐波那契数"""
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# 打印前 10 个斐波那契数
for i in range(10):
print(fibonacci(i), end=" ")
# 输出: 0 1 1 2 3 5 8 13 21 34
8.3 尾递归优化(模拟)
def factorial_tail(n, accumulator=1):
"""尾递归风格的阶乘(Python 不优化尾递归,但代码风格如此)"""
if n <= 1:
return accumulator
return factorial_tail(n - 1, n * accumulator)
print(factorial_tail(5)) # 120
8.4 递归深度限制
import sys
print(f"默认递归深度限制: {sys.getrecursionlimit()}")
# 默认通常是 1000
# 可以修改(谨慎使用)
# sys.setrecursionlimit(2000)
9. 生成器函数
9.1 使用 yield
def countdown(n):
"""从 n 倒数到 1"""
while n > 0:
yield n
n -= 1
# 使用生成器
counter = countdown(5)
for num in counter:
print(num, end=" ")
# 输出: 5 4 3 2 1
9.2 生成器表达式
# 列表推导式(一次性生成所有数据)
squares_list = [x**2 for x in range(1000000)] # 占用大量内存
# 生成器表达式(惰性求值)
squares_gen = (x**2 for x in range(1000000)) # 几乎不占用内存
# 按需获取
print(next(squares_gen)) # 0
print(next(squares_gen)) # 1
9.3 斐波那契生成器
def fibonacci_generator(limit):
"""生成斐波那契数列,直到达到限制"""
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
for num in fibonacci_generator(100):
print(num, end=" ")
# 输出: 0 1 1 2 3 5 8 13 21 34 55 89
9.4 yield from(Python 3.3+)
def sub_generator():
yield 1
yield 2
def main_generator():
yield "开始"
yield from sub_generator() # 委托子生成器
yield "结束"
for item in main_generator():
print(item)
# 输出:
# 开始
# 1
# 2
# 结束
10. 闭包
10.1 基本概念
闭包是指引用了外部作用域变量的函数,即使外部函数已经执行完毕
def make_power(exponent):
"""创建求幂函数"""
def power(base):
return base ** exponent
return power
square = make_power(2)
cube = make_power(3)
print(square(4)) # 16
print(cube(3)) # 27
10.2 闭包与状态保持
def make_averager():
"""创建平均值计算器,保持历史数据"""
numbers = []
def averager(value):
numbers.append(value)
return sum(numbers) / len(numbers)
return averager
avg = make_averager()
print(avg(10)) # 10.0
print(avg(20)) # 15.0
print(avg(30)) # 20.0
10.3 闭包与 nonlocal
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
# 查看闭包变量
counter.get_count = lambda: count
return counter
c = make_counter()
print(c()) # 1
print(c()) # 2
print(c.get_count()) # 2
10.4 闭包 vs 类
# 使用闭包实现简单计数器
def counter_closure():
count = [0] # 使用可变对象避免 nonlocal
def increment():
count[0] += 1
return count[0]
return increment
# 使用类实现相同功能
class CounterClass:
def __init__(self):
self.count = 0
def increment(self):
self.count += 1
return self.count
# 两者功能相同
closure_counter = counter_closure()
class_counter = CounterClass()
print(closure_counter()) # 1
print(class_counter.increment()) # 1
附录:函数速查表
| 特性 | 语法 | 示例 |
|---|---|---|
| 定义函数 | def name(): | def foo(): pass |
| 默认参数 | def name(arg=val) | def foo(x=1): |
| 可变位置参数 | *args | def foo(*args): |
| 可变关键字参数 | **kwargs | def foo(**kwargs): |
| 仅限位置参数 | / | def foo(x, /): |
| 仅限关键字参数 | * | def foo(*, x): |
| Lambda | lambda args: expr | lambda x: x**2 |
| 装饰器 | @decorator | @timer |
| 生成器 | yield | def gen(): yield 1 |
| 类型注解 | arg: type | def foo(x: int) -> str: |
学习建议:
- 从基础函数定义开始,逐步掌握参数传递
- 理解作用域规则是避免 bug 的关键
- 装饰器和生成器是 Python 高级编程的核心
- 多写代码,多调试,才能真正掌握函数精髓
更多推荐



所有评论(0)