函数与模块
函数是组织代码的基本单元,模块是组织函数的方式。
函数基础
定义函数
# 基本语法
def greet():
print("Hello, World!")
# 调用函数
greet() # Hello, World!
# 带参数的函数
def greet_user(name):
print(f"Hello, {name}!")
greet_user("张三") # Hello, 张三!
# 带返回值的函数
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
参数类型
# 1. 位置参数
def power(base, exp):
return base ** exp
print(power(2, 3)) # 8
# 2. 关键字参数
print(power(exp=3, base=2)) # 8
# 3. 默认参数
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("张三") # Hello, 张三!
greet("张三", "Hi") # Hi, 张三!
# 4. 可变位置参数 *args
def sum_all(*numbers):
return sum(numbers)
print(sum_all(1, 2, 3, 4, 5)) # 15
# 5. 可变关键字参数 **kwargs
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="张三", age=25, city="北京")
# 6. 混合使用
def func(a, b, *args, c=10, **kwargs):
print(f"a={a}, b={b}")
print(f"args={args}")
print(f"c={c}")
print(f"kwargs={kwargs}")
func(1, 2, 3, 4, c=20, d=30, e=40)
参数顺序规则
# 正确顺序:位置参数 → *args → 默认参数 → **kwargs
def func(a, b, *args, c=10, **kwargs):
pass
# 强制关键字参数(*后面的参数必须用关键字)
def greet(name, *, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("张三") # Hello, 张三!
greet("张三", greeting="Hi") # Hi, 张三!
# greet("张三", "Hi") # TypeError!
返回值
# 返回单个值
def square(x):
return x ** 2
# 返回多个值(实际是元组)
def get_min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = get_min_max([3, 1, 4, 1, 5, 9])
print(f"最小: {minimum}, 最大: {maximum}")
# 提前返回
def check_age(age):
if age < 0:
return "无效年龄"
if age < 18:
return "未成年"
return "成年"
# 没有 return 语句时返回 None
def do_nothing():
pass
print(do_nothing()) # None
典型案例:用户注册验证
def validate_registration(username, password, email):
"""验证用户注册信息"""
errors = []
# 验证用户名
if len(username) < 3:
errors.append("用户名至少3个字符")
if not username.isalnum():
errors.append("用户名只能包含字母和数字")
# 验证密码
if len(password) < 6:
errors.append("密码至少6个字符")
# 验证邮箱
if "@" not in email or "." not in email:
errors.append("邮箱格式不正确")
if errors:
return False, errors
return True, []
# 使用
is_valid, errors = validate_registration("ab", "123", "test")
if not is_valid:
for error in errors:
print(f"错误: {error}")
变量作用域
# 全局变量
global_var = "我是全局变量"
def func():
# 局部变量
local_var = "我是局部变量"
print(global_var) # 可以读取全局变量
print(local_var)
func()
# print(local_var) # NameError: 局部变量在外部不可见
# 修改全局变量需要 global 声明
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
# 嵌套函数的 nonlocal
def outer():
x = 10
def inner():
nonlocal x
x += 1
print(f"inner: x = {x}")
inner()
print(f"outer: x = {x}")
outer()
# inner: x = 11
# outer: x = 11
匿名函数 (lambda)
# 基本语法
square = lambda x: x ** 2
print(square(5)) # 25
# 多个参数
add = lambda a, b: a + b
print(add(3, 5)) # 8
# 常用于排序
students = [
{"name": "张三", "score": 85},
{"name": "李四", "score": 92},
{"name": "王五", "score": 78}
]
# 按分数排序
sorted_students = sorted(students, key=lambda s: s["score"])
print([s["name"] for s in sorted_students]) # ['王五', '张三', '李四']
# 按分数降序
sorted_students = sorted(students, key=lambda s: s["score"], reverse=True)
高阶函数
高阶函数是接收函数作为参数或返回函数的函数。
map()
# 对每个元素应用函数
numbers = [1, 2, 3, 4, 5]
# 使用 map
squares = list(map(lambda x: x**2, numbers))
print(squares) # [1, 4, 9, 16, 25]
# 等价的列表推导式
squares = [x**2 for x in numbers]
# 多个序列
a = [1, 2, 3]
b = [4, 5, 6]
sums = list(map(lambda x, y: x + y, a, b))
print(sums) # [5, 7, 9]
filter()
# 过滤元素
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用 filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# 等价的列表推导式
evens = [x for x in numbers if x % 2 == 0]
reduce()
from functools import reduce
# 累积计算
numbers = [1, 2, 3, 4, 5]
# 求和
total = reduce(lambda x, y: x + y, numbers)
print(total) # 15
# 求积
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
# 求最大值
maximum = reduce(lambda x, y: x if x > y else y, numbers)
print(maximum) # 5
sorted() 与 key
# 字符串按长度排序
words = ["apple", "pie", "banana", "cherry"]
sorted_words = sorted(words, key=len)
print(sorted_words) # ['pie', 'apple', 'cherry', 'banana']
# 忽略大小写排序
words = ["Apple", "banana", "Cherry"]
sorted_words = sorted(words, key=str.lower)
print(sorted_words) # ['Apple', 'banana', 'Cherry']
# 复杂对象排序
from operator import itemgetter
students = [
{"name": "张三", "age": 20, "score": 85},
{"name": "李四", "age": 19, "score": 92},
{"name": "王五", "age": 21, "score": 78}
]
# 按年龄排序
by_age = sorted(students, key=itemgetter("age"))
# 多字段排序:先按分数降序,再按年龄升序
by_score_age = sorted(students, key=lambda s: (-s["score"], s["age"]))
装饰器
装饰器用于在不修改函数代码的情况下增强函数功能。
# 基本装饰器
def my_decorator(func):
def wrapper(*args, **kwargs):
print("函数执行前")
result = func(*args, **kwargs)
print("函数执行后")
return result
return wrapper
@my_decorator
def say_hello(name):
print(f"Hello, {name}!")
say_hello("张三")
# 函数执行前
# Hello, 张三!
# 函数执行后
典型案例:计时装饰器
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)
print("函数执行完成")
slow_function()
# 函数执行完成
# slow_function 执行耗时: 1.0012秒
典型案例:权限检查装饰器
def require_auth(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.get("is_authenticated"):
print("请先登录!")
return None
return func(user, *args, **kwargs)
return wrapper
@require_auth
def get_user_profile(user):
return f"用户资料: {user['name']}"
# 测试
guest = {"name": "访客", "is_authenticated": False}
member = {"name": "张三", "is_authenticated": True}
print(get_user_profile(guest)) # 请先登录! None
print(get_user_profile(member)) # 用户资料: 张三
递归函数
# 阶乘
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
# 斐波那契(低效版本)
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# 带缓存的斐波那契(高效)
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_cached(n):
if n <= 1:
return n
return fib_cached(n - 1) + fib_cached(n - 2)
print(fib_cached(100)) # 354224848179261915075
模块
导入模块
# 导入整个模块
import math
print(math.sqrt(16)) # 4.0
# 导入特定函数
from math import sqrt, pi
print(sqrt(16)) # 4.0
print(pi) # 3.141592653589793
# 导入所有(不推荐)
from math import *
# 别名
import numpy as np
from math import sqrt as square_root
# 导入自己的模块
# 假设有文件 mymodule.py
import mymodule
from mymodule import my_function
创建模块
# mymath.py
"""这是我的数学模块"""
PI = 3.14159
def circle_area(radius):
"""计算圆的面积"""
return PI * radius ** 2
def circle_circumference(radius):
"""计算圆的周长"""
return 2 * PI * radius
# 仅在直接运行时执行
if __name__ == "__main__":
print(circle_area(5))
# main.py
import mymath
print(mymath.PI)
print(mymath.circle_area(5))
包
包是包含多个模块的目录,必须有 __init__.py 文件。
mypackage/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
module3.py
# 导入包中的模块
from mypackage import module1
from mypackage.subpackage import module3
常用标准库
# os - 操作系统接口
import os
print(os.getcwd()) # 当前目录
print(os.listdir(".")) # 列出目录内容
os.makedirs("path/to/dir", exist_ok=True) # 创建目录
# sys - 系统相关
import sys
print(sys.version) # Python 版本
print(sys.path) # 模块搜索路径
sys.exit(0) # 退出程序
# datetime - 日期时间
from datetime import datetime, timedelta
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))
tomorrow = now + timedelta(days=1)
# random - 随机数
import random
print(random.randint(1, 100)) # 随机整数
print(random.choice([1, 2, 3])) # 随机选择
random.shuffle([1, 2, 3, 4, 5]) # 打乱列表
# json - JSON 处理
import json
data = {"name": "张三", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)
parsed = json.loads(json_str)
# re - 正则表达式
import re
pattern = r"\d+"
matches = re.findall(pattern, "abc123def456")
print(matches) # ['123', '456']
典型案例:日志模块
# logger.py
import datetime
LOG_LEVELS = {
"DEBUG": 0,
"INFO": 1,
"WARNING": 2,
"ERROR": 3
}
current_level = "INFO"
def log(level, message):
if LOG_LEVELS.get(level, 0) >= LOG_LEVELS.get(current_level, 0):
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] [{level}] {message}")
def debug(message):
log("DEBUG", message)
def info(message):
log("INFO", message)
def warning(message):
log("WARNING", message)
def error(message):
log("ERROR", message)
def set_level(level):
global current_level
current_level = level
练习
练习1:实现 map 函数
def my_map(func, iterable):
result = []
for item in iterable:
result.append(func(item))
return result
# 测试
numbers = [1, 2, 3, 4, 5]
squares = my_map(lambda x: x**2, numbers)
print(squares) # [1, 4, 9, 16, 25]
练习2:缓存装饰器
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def expensive_computation(n):
print(f"计算 {n}")
return n ** 2
print(expensive_computation(5)) # 计算 5 → 25
print(expensive_computation(5)) # 直接返回 25(没有重新计算)
小结
- 函数使用
def定义,return返回值 - 参数类型:位置参数、默认参数、
*args、**kwargs lambda创建匿名函数map、filter、reduce是常用高阶函数- 装饰器用于增强函数功能
- 使用
import导入模块 if __name__ == "__main__"用于模块的入口代码