1. Python函数基础概念解析
函数是Python编程中最重要的基础构件之一,它就像厨房里的多功能料理机 - 你只需要把食材放进去,按下按钮,就能得到处理好的成品。在Python中,函数允许我们将一段可重用的代码封装起来,通过简单的调用来执行复杂的操作。
1.1 为什么需要函数
想象你正在编写一个计算员工薪资的程序。如果没有函数,每次计算薪资时都需要重复写相同的计算公式。而使用函数后,你只需要定义一次计算逻辑,然后在需要的地方调用即可。这不仅减少了代码量,更重要的是:
- 提高代码可读性:良好的函数命名可以让代码自文档化
- 便于维护:修改只需在一处进行,不会影响其他部分
- 降低复杂度:将大问题分解为小函数,逐个击破
- 促进代码复用:一次编写,多次使用
1.2 函数定义的基本语法
Python中使用def关键字定义函数,基本结构如下:
python复制def function_name(parameters):
"""函数文档字符串"""
# 函数体
return [expression]
这里有几个关键组成部分:
def:声明这是一个函数定义function_name:函数标识符,应使用小写字母和下划线parameters:可选的形式参数列表"""文档字符串""":描述函数功能的字符串,可通过help()查看- 函数体:实现具体功能的代码块
return:可选,用于返回结果。没有return语句时函数返回None
提示:函数名应该清晰表达其功能,避免使用模糊的名称如
do_stuff()或process_data()
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 函数参数详解
2.1 位置参数与关键字参数
Python函数支持两种主要的参数传递方式:
python复制def greet(name, message):
print(f"{message}, {name}!")
# 位置参数调用
greet("Alice", "Hello") # 输出: Hello, Alice!
# 关键字参数调用
greet(message="Hi", name="Bob") # 输出: Hi, Bob!
位置参数必须按照定义时的顺序传递,而关键字参数则通过参数名指定,顺序不重要。关键字参数能显著提高代码可读性,特别是在处理多个参数时。
2.2 默认参数值
我们可以为参数指定默认值,这使得参数变为可选的:
python复制def power(base, exponent=2):
return base ** exponent
print(power(3)) # 输出: 9 (使用默认exponent=2)
print(power(3, 3)) # 输出: 27
注意:默认参数在函数定义时计算并保存,因此对于可变对象(如列表、字典)要特别小心。应该使用None作为默认值,然后在函数内初始化可变对象。
2.3 可变参数:*args和**kwargs
当需要处理不确定数量的参数时,可以使用*args和**kwargs:
python复制def sum_numbers(*args):
return sum(args)
print(sum_numbers(1, 2, 3)) # 输出: 6
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)
# 输出:
# name: Alice
# age: 25
*args收集所有位置参数为一个元组,**kwargs收集所有关键字参数为一个字典。这两个特性使得函数接口非常灵活。
3. 变量作用域与生命周期
3.1 局部变量与全局变量
理解变量作用域对编写可靠的函数至关重要:
python复制x = 10 # 全局变量
def my_func():
y = 5 # 局部变量
print(x) # 可以访问全局变量
print(y)
my_func()
print(y) # 报错: NameError, y未定义
- 局部变量:函数内部定义的变量,只能在函数内访问
- 全局变量:函数外部定义的变量,可以在整个模块中访问
3.2 global和nonlocal关键字
如果需要修改全局变量或在嵌套函数中修改外部函数的变量:
python复制count = 0
def increment():
global count
count += 1
increment()
print(count) # 输出: 1
def outer():
x = 10
def inner():
nonlocal x
x = 20
inner()
print(x) # 输出: 20
global:声明使用全局变量nonlocal:在嵌套函数中声明使用外层函数的变量
实际经验:过度使用全局变量会使代码难以维护和调试。更好的做法是将需要共享的数据作为参数传递。
4. 函数的高级特性
4.1 函数作为一等公民
在Python中,函数是"一等公民",这意味着它们可以:
- 被赋值给变量
- 作为参数传递给其他函数
- 作为其他函数的返回值
- 存储在数据结构中
python复制def greet(name):
return f"Hello, {name}!"
# 赋值给变量
my_func = greet
print(my_func("Alice")) # 输出: Hello, Alice!
# 作为参数传递
def call_func(func, arg):
return func(arg)
print(call_func(greet, "Bob")) # 输出: Hello, Bob!
4.2 嵌套函数与闭包
Python允许在函数内部定义函数,这种结构称为嵌套函数:
python复制def outer():
message = "Hello"
def inner(name):
print(f"{message}, {name}!")
return inner
my_func = outer()
my_func("Alice") # 输出: Hello, Alice!
闭包是指内部函数记住了它被创建时的环境(即外部函数的局部变量)。上面的例子中,inner函数就是一个闭包,它记住了message变量的值。
4.3 装饰器基础
装饰器是Python中极为强大的特性,它允许在不修改原函数代码的情况下扩展功能:
python复制def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# Something is happening before the function is called.
# Hello!
# Something is happening after the function is called.
装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数。@语法糖使得应用装饰器更加简洁。
5. 常见问题与最佳实践
5.1 函数设计原则
- 单一职责原则:一个函数只做一件事
- 保持简短:理想情况下不超过20行
- 明确命名:函数名应准确描述其功能
- 避免副作用:函数应该只通过return返回值,而不是修改外部状态
- 文档字符串:为每个函数编写清晰的文档
5.2 常见错误与调试
- 忘记return语句:函数默认返回None
- 修改可变默认参数:
python复制def append_to(element, to=[]): # 错误的做法 to.append(element) return to # 应该这样写 def append_to(element, to=None): if to is None: to = [] to.append(element) return to - 混淆局部和全局变量:使用global关键字时要谨慎
- 参数顺序错误:使用关键字参数可以避免这个问题
5.3 性能考虑
- 函数调用有一定开销,在性能关键的循环中,可以考虑内联代码
- 对于简单的操作,lambda函数可能比普通函数更高效
- 使用
functools.lru_cache可以缓存函数结果,避免重复计算
python复制from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
6. 实际应用案例
6.1 数据处理管道
函数可以串联起来形成数据处理管道:
python复制def read_data(filename):
with open(filename) as f:
return [line.strip() for line in f]
def filter_data(data, keyword):
return [item for item in data if keyword in item]
def process_data(data):
return [item.upper() for item in data]
# 组合使用
data = read_data("input.txt")
filtered = filter_data(data, "important")
processed = process_data(filtered)
6.2 配置模式
使用函数可以实现灵活的配置模式:
python复制def create_processor(transform_func):
def processor(data):
# 预处理
cleaned = [item.strip() for item in data]
# 应用转换函数
transformed = transform_func(cleaned)
# 后处理
return [item for item in transformed if item]
return processor
# 创建特定的处理器
upper_processor = create_processor(lambda x: [item.upper() for item in x])
reverse_processor = create_processor(lambda x: [item[::-1] for item in x])
data = [" hello ", " world "]
print(upper_processor(data)) # 输出: ['HELLO', 'WORLD']
print(reverse_processor(data)) # 输出: [' olleh ', ' dlrow ']
6.3 回调机制
函数作为回调在事件驱动编程中非常有用:
python复制class Button:
def __init__(self):
self.callbacks = []
def register_callback(self, func):
self.callbacks.append(func)
def click(self):
print("Button clicked!")
for callback in self.callbacks:
callback()
def say_hello():
print("Hello!")
def say_goodbye():
print("Goodbye!")
btn = Button()
btn.register_callback(say_hello)
btn.register_callback(say_goodbye)
btn.click()
# 输出:
# Button clicked!
# Hello!
# Goodbye!
7. 函数式编程基础
Python虽然不是纯函数式语言,但支持许多函数式编程特性:
7.1 map、filter和reduce
python复制numbers = [1, 2, 3, 4, 5]
# map: 对每个元素应用函数
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25]
# filter: 过滤元素
evens = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
# reduce: 累积计算
from functools import reduce
product = reduce(lambda x, y: x * y, numbers) # 120
7.2 列表推导式 vs map/filter
列表推导式通常比map/filter更直观:
python复制# 使用map/filter
result = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))
# 使用列表推导式
result = [x**2 for x in numbers if x % 2 == 0]
7.3 偏函数(Partial Functions)
functools.partial可以固定函数的部分参数,创建新函数:
python复制from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5)) # 25
print(cube(5)) # 125
8. 类型提示与函数注解
Python 3.5+支持类型提示,可以提高代码可读性和IDE支持:
python复制from typing import List, Dict, Optional
def process_items(
items: List[str],
counts: Dict[str, int],
limit: Optional[int] = None
) -> bool:
"""处理项目列表
Args:
items: 字符串列表
counts: 字符串到整数的映射
limit: 可选的最大处理数量
Returns:
处理是否成功
"""
# 实现代码...
return True
类型提示不会影响运行时行为,但可以被mypy等工具用于静态类型检查。
9. 生成器函数
使用yield关键字可以创建生成器函数,它返回一个迭代器:
python复制def countdown(n):
while n > 0:
yield n
n -= 1
for i in countdown(5):
print(i) # 输出: 5 4 3 2 1
生成器函数在需要惰性计算或处理大数据集时非常有用,因为它们不会一次性生成所有值,而是按需生成。
10. 函数调试技巧
10.1 使用print调试
虽然简单,但在函数中添加print语句仍然是有效的调试方法:
python复制def complex_calculation(a, b):
print(f"输入参数: a={a}, b={b}") # 调试输出
result = (a ** 2) + (b ** 2)
print(f"计算结果: {result}") # 调试输出
return result
10.2 使用logging模块
对于更专业的调试,可以使用logging模块:
python复制import logging
logging.basicConfig(level=logging.DEBUG)
def complex_calculation(a, b):
logging.debug(f"输入参数: a={a}, b={b}")
result = (a ** 2) + (b ** 2)
logging.debug(f"计算结果: {result}")
return result
10.3 使用pdb调试器
Python内置的pdb调试器可以单步执行函数:
python复制import pdb
def problematic_function(x):
pdb.set_trace() # 设置断点
result = x * 2
return result
运行时会进入交互式调试模式,可以检查变量、单步执行等。
11. 函数性能优化
11.1 避免不必要的计算
python复制# 不优化的版本
def calculate_stats(data):
avg = sum(data) / len(data)
maximum = max(data)
minimum = min(data)
return {"avg": avg, "max": maximum, "min": minimum}
# 优化版本 - 只遍历一次数据
def calculate_stats_optimized(data):
total = 0
maximum = minimum = data[0]
for num in data:
total += num
if num > maximum:
maximum = num
if num < minimum:
minimum = num
return {"avg": total / len(data), "max": maximum, "min": minimum}
11.2 使用内置函数
内置函数通常是用C实现的,比纯Python实现快得多:
python复制# 较慢的实现
def sum_squares(numbers):
total = 0
for num in numbers:
total += num ** 2
return total
# 更快的实现
def sum_squares_fast(numbers):
return sum(num ** 2 for num in numbers)
11.3 使用functools.cache
Python 3.9+提供了简单的缓存装饰器:
python复制from functools import cache
@cache
def factorial(n):
return n * factorial(n-1) if n else 1
对于递归函数,缓存可以显著提高性能。
12. 测试函数
为函数编写测试是保证代码质量的重要手段:
12.1 使用assert进行简单测试
python复制def add(a, b):
return a + b
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
12.2 使用unittest模块
python复制import unittest
class TestAddFunction(unittest.TestCase):
def test_add_positive(self):
self.assertEqual(add(2, 3), 5)
def test_add_negative(self):
self.assertEqual(add(-1, 1), 0)
def test_add_zero(self):
self.assertEqual(add(0, 0), 0)
if __name__ == "__main__":
unittest.main()
12.3 使用pytest框架
pytest提供了更简洁的测试语法:
python复制# test_add.py
def test_add_positive():
assert add(2, 3) == 5
def test_add_negative():
assert add(-1, 1) == 0
运行测试只需在命令行执行pytest test_add.py。
13. 函数文档与注释
良好的文档和注释对维护代码至关重要:
13.1 文档字符串(Docstrings)
Python使用三引号字符串作为函数文档:
python复制def calculate_area(length, width):
"""计算矩形面积
Args:
length (float): 矩形的长度
width (float): 矩形的宽度
Returns:
float: 矩形的面积 (length * width)
Raises:
ValueError: 如果长度或宽度为负数
"""
if length < 0 or width < 0:
raise ValueError("长度和宽度必须为正数")
return length * width
13.2 类型注解与文档
结合类型提示和文档字符串可以提供更完整的信息:
python复制from typing import Tuple
def divide(dividend: float, divisor: float) -> Tuple[float, float]:
"""执行除法运算,返回商和余数
Args:
dividend: 被除数
divisor: 除数
Returns:
包含商和余数的元组
Raises:
ZeroDivisionError: 如果除数为零
"""
if divisor == 0:
raise ZeroDivisionError("除数不能为零")
quotient = dividend // divisor
remainder = dividend % divisor
return quotient, remainder
14. 函数设计模式
14.1 策略模式
使用函数实现策略模式:
python复制def strategy_add(a, b):
return a + b
def strategy_multiply(a, b):
return a * b
class Calculator:
def __init__(self, strategy):
self.strategy = strategy
def execute(self, a, b):
return self.strategy(a, b)
calc = Calculator(strategy_add)
print(calc.execute(3, 4)) # 7
calc = Calculator(strategy_multiply)
print(calc.execute(3, 4)) # 12
14.2 工厂模式
使用函数作为工厂创建对象:
python复制def create_person(kind, *args, **kwargs):
if kind == "student":
return Student(*args, **kwargs)
elif kind == "teacher":
return Teacher(*args, **kwargs)
else:
raise ValueError(f"未知的类型: {kind}")
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
class Teacher:
def __init__(self, name, subject):
self.name = name
self.subject = subject
student = create_person("student", "Alice", "A")
teacher = create_person("teacher", "Bob", "Math")
15. 函数与面向对象编程
15.1 类方法 vs 静态方法 vs 实例方法
python复制class MyClass:
def instance_method(self):
print(f"实例方法,self={self}")
@classmethod
def class_method(cls):
print(f"类方法,cls={cls}")
@staticmethod
def static_method():
print("静态方法")
obj = MyClass()
obj.instance_method() # 调用实例方法
MyClass.class_method() # 调用类方法
MyClass.static_method() # 调用静态方法
- 实例方法:接收实例作为第一个参数(self)
- 类方法:接收类作为第一个参数(cls)
- 静态方法:不接收特殊参数
15.2 将函数作为方法使用
函数可以动态地添加到类中作为方法:
python复制class Person:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, my name is {self.name}")
Person.greet = greet # 将函数添加为类的方法
p = Person("Alice")
p.greet() # 输出: Hello, my name is Alice
16. 函数与模块化设计
16.1 将相关函数组织到模块中
良好的模块化设计可以提高代码的可维护性:
python复制# geometry.py
"""几何计算模块"""
def area_of_circle(radius):
return 3.14159 * radius ** 2
def area_of_rectangle(length, width):
return length * width
def area_of_triangle(base, height):
return 0.5 * base * height
# main.py
from geometry import area_of_circle, area_of_rectangle
print(area_of_circle(5))
print(area_of_rectangle(4, 6))
16.2 使用__all__控制导入
在模块中使用__all__可以控制from module import *的行为:
python复制# geometry.py
__all__ = ['area_of_circle', 'area_of_rectangle']
def area_of_circle(radius):
return 3.14159 * radius ** 2
def area_of_rectangle(length, width):
return length * width
def _internal_helper():
pass # 内部使用的函数,不会被import *导入
17. 函数与异常处理
17.1 函数中的异常处理
python复制def divide(a, b):
try:
return a / b
except ZeroDivisionError:
print("错误:除数不能为零")
return None
except TypeError:
print("错误:参数类型不正确")
return None
print(divide(10, 2)) # 5.0
print(divide(10, 0)) # 错误:除数不能为零 None
print(divide("10", 2)) # 错误:参数类型不正确 None
17.2 自定义异常
可以定义特定于函数的异常:
python复制class InvalidInputError(Exception):
pass
def process_input(value):
if not isinstance(value, (int, float)):
raise InvalidInputError("输入必须是数字")
return value * 2
try:
print(process_input(5)) # 10
print(process_input("text")) # 引发InvalidInputError
except InvalidInputError as e:
print(f"输入无效: {e}")
18. 函数与并发编程
18.1 使用多线程执行函数
python复制import threading
import time
def worker(name, delay):
print(f"Worker {name} 开始")
time.sleep(delay)
print(f"Worker {name} 完成")
threads = []
for i in range(3):
t = threading.Thread(target=worker, args=(i, i+1))
threads.append(t)
t.start()
for t in threads:
t.join()
18.2 使用多进程执行函数
对于CPU密集型任务,多进程可能更合适:
python复制import multiprocessing
def cpu_intensive_task(n):
return sum(i * i for i in range(n))
if __name__ == "__main__":
with multiprocessing.Pool() as pool:
results = pool.map(cpu_intensive_task, [10**6, 10**7, 10**8])
print(results)
19. 函数与异步编程
19.1 异步函数基础
Python的async/await语法允许编写异步代码:
python复制import asyncio
async def fetch_data():
print("开始获取数据")
await asyncio.sleep(2) # 模拟I/O操作
print("数据获取完成")
return {"data": 123}
async def main():
task = asyncio.create_task(fetch_data())
print("执行其他任务...")
data = await task
print(f"获取到的数据: {data}")
asyncio.run(main())
19.2 异步函数与同步代码的交互
在异步函数中调用同步函数,可以使用run_in_executor:
python复制import asyncio
import time
def blocking_io():
time.sleep(1)
return "IO结果"
async def main():
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(None, blocking_io)
print(result)
asyncio.run(main())
20. 函数式编程实践
20.1 高阶函数应用
高阶函数是接受或返回函数的函数:
python复制def apply_operation(func, a, b):
return func(a, b)
def add(x, y):
return x + y
def multiply(x, y):
return x * y
print(apply_operation(add, 3, 4)) # 7
print(apply_operation(multiply, 3, 4)) # 12
20.2 函数组合
可以将多个函数组合成一个新函数:
python复制def compose(f, g):
return lambda x: f(g(x))
def add_one(x):
return x + 1
def square(x):
return x * x
add_one_then_square = compose(square, add_one)
print(add_one_then_square(2)) # (2 + 1)^2 = 9
21. 函数与元编程
21.1 动态创建函数
可以使用types.FunctionType动态创建函数:
python复制import types
def create_function(name, arg_names, code):
# 编译代码
code_obj = compile(code, "<string>", "exec")
# 创建函数对象
func = types.FunctionType(code_obj.co_consts[0], globals(), name)
# 设置参数名
func.__code__ = func.__code__.replace(
co_varnames=("",) + arg_names,
co_argcount=len(arg_names)
)
return func
# 动态创建add函数
add_func = create_function(
"add",
("a", "b"),
"def anonymous(a, b): return a + b"
)
print(add_func(2, 3)) # 5
21.2 函数装饰器的高级用法
装饰器可以接受参数:
python复制def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(num_times=3)
def greet(name):
print(f"Hello {name}")
greet("Alice")
# 输出:
# Hello Alice
# Hello Alice
# Hello Alice
22. 函数与元类
虽然不常见,但函数可以在元类中使用:
python复制def add_method(cls):
def method(self):
return "添加的方法"
cls.new_method = method
return cls
@add_method
class MyClass:
pass
obj = MyClass()
print(obj.new_method()) # 输出: 添加的方法
23. 函数与描述符
函数本质上也是描述符,这解释了为什么实例方法能自动接收self参数:
python复制class FunctionAsDescriptor:
def __init__(self, func):
self.func = func
def __get__(self, obj, objtype=None):
if obj is None:
return self.func
return types.MethodType(self.func, obj)
class MyClass:
@FunctionAsDescriptor
def method(self):
return "方法调用"
obj = MyClass()
print(obj.method()) # 输出: 方法调用
24. 函数与代码分析
24.1 检查函数属性
Python函数有许多有用的属性:
python复制def example(a, b=1, *args, **kwargs):
"""示例函数"""
pass
print(example.__name__) # 'example'
print(example.__doc__) # '示例函数'
print(example.__defaults__) # (1,)
print(example.__code__.co_varnames) # ('a', 'b', 'args', 'kwargs')
24.2 动态修改函数
可以动态修改函数的属性:
python复制def original():
return "原始函数"
def new_behavior():
return "修改后的行为"
original.__code__ = new_behavior.__code__
print(original()) # 输出: 修改后的行为
25. 函数与性能分析
25.1 使用timeit测量函数执行时间
python复制import timeit
def test_func():
return sum(range(10000))
time_taken = timeit.timeit(test_func, number=1000)
print(f"平均执行时间: {time_taken / 1000:.6f}秒")
25.2 使用cProfile分析函数性能
python复制import cProfile
def slow_function():
total = 0
for i in range(10000):
for j in range(100):
total += i * j
return total
cProfile.run('slow_function()')
26. 函数与C扩展
Python函数可以与C扩展交互:
python复制# 假设有一个编译好的C扩展模块叫fastmath
import fastmath
def python_sum(numbers):
return sum(numbers)
# 使用C扩展函数
def hybrid_sum(numbers):
if len(numbers) < 1000:
return python_sum(numbers)
else:
return fastmath.sum(numbers)
27. 函数与JIT编译
使用PyPy或Numba等工具可以加速函数执行:
python复制# 使用Numba JIT编译
from numba import jit
@jit(nopython=True)
def numba_sum(arr):
total = 0.0
for x in arr:
total += x
return total
import numpy as np
large_array = np.random.rand(1000000)
print(numba_sum(large_array))
28. 函数与网络编程
28.1 回调式网络编程
python复制import socket
def handle_client(conn, addr):
print(f"连接来自 {addr}")
with conn:
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
def start_server(host='localhost', port=65432):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((host, port))
s.listen()
while True:
conn, addr = s.accept()
handle_client(conn, addr)
28.2 使用函数处理HTTP请求
python复制from http.server import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Hello, World!")
def run_server(server_class=HTTPServer, handler_class=Handler):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
run_server()
29. 函数与GUI编程
29.1 Tkinter事件处理
python复制import tkinter as tk
def on_button_click():
label.config(text="按钮被点击!")
root = tk.Tk()
button = tk.Button(root, text="点击我", command=on_button_click)
button.pack()
label = tk.Label(root, text="等待点击...")
label.pack()
root.mainloop()
29.2 使用函数组织GUI代码
python复制def create_gui():
root = tk.Tk()
setup_main_window(root)
add_widgets(root)
return root
def setup_main_window(root):
root.title("我的应用")
root.geometry("400x300")
def add_widgets(root):
frame = tk.Frame(root)
frame.pack()
tk.Label(frame, text="用户名:").grid(row=0, column=0)
tk.Entry(frame).grid(row=0, column=1)
tk.Button(frame, text="登录", command=login).grid(row=1, columnspan=2)
def login():
print("登录逻辑...")
create_gui().mainloop()
30. 函数与数据库交互
30.1 使用函数封装数据库操作
python复制import sqlite3
def create_connection(db_file):
"""创建数据库连接"""
conn = None
try:
conn = sqlite3.connect(db_file)
return conn
except sqlite3.Error as e:
print(e)
return conn
def create_table(conn, create_table_sql):
"""创建表"""
try:
c = conn.cursor()
c.execute(create_table_sql)
except sqlite3.Error as e:
print(e)
def main():
database = "mydatabase.db"
sql_create_projects_table = """CREATE TABLE IF NOT EXISTS projects (
id integer PRIMARY KEY,
name text NOT NULL,
begin_date text,
end_date text
);"""
conn = create_connection(database)
if conn is not None:
create_table(conn, sql_create_projects_table)
else:
print("无法创建数据库连接")
if __name__ == "__main__":
main()
30.2 使用上下文管理器处理数据库连接
python复制from contextlib import contextmanager
@contextmanager
def db_connection(db_file):
conn = sqlite3.connect(db_file)
try:
yield conn
finally:
conn.close()
def query_data():
with db_connection("mydatabase.db") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM projects")
return cursor.fetchall()
31. 函数与文件处理
31.1 处理CSV文件
python复制import csv
def read_csv(filename):
with open(filename, mode='r') as file:
reader = csv.DictReader(file)
return [row for row in reader]
def write_csv(filename, data, fieldnames):
with open(filename, mode='w', newline='') as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
# 使用示例
data = read_csv("input.csv")
processed_data = process_data(data) # 假设有process_data函数
write_csv("output.csv", processed_data, fieldnames=["name", "value"])
31.2 处理JSON文件
python复制import json
def read_json(filename):
with open(filename, 'r') as file:
return json.load(file)
def write_json(filename, data):
with open(filename, 'w') as file:
json.dump(data, file, indent=2)
# 使用示例
config = read_json("config.json")
config["new_setting"] = "value"
write_json("config.json", config)
32. 函数与正则表达式
32.1 使用函数封装正则操作
python复制import re
def extract_emails(text):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.findall(pattern, text)
def is_valid_phone(number):
pattern = r'^(\+\d{1,3}[- ]?)?\d{10}$'
return bool(re.fullmatch
