Python高级特性 - 提升代码质量与效率
1. 高级特性概述
作为Java开发者,您已经掌握了面向对象编程的核心概念。Python除了支持这些基本概念外,还提供了许多高级特性,可以让您的代码更加简洁、高效和优雅。这些特性在Java中可能没有直接对应物,或者实现起来比较复杂。
2. 装饰器(Decorators)
装饰器是Python中非常强大的特性,允许您修改函数或类的行为,而不需要直接修改其源代码。
基本装饰器
python
# 定义装饰器
def timer(func):
"""测量函数执行时间的装饰器"""
import time
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数 {func.__name__} 执行时间: {end_time - start_time:.6f} 秒")
return result
return wrapper
# 使用装饰器
@timer
def slow_function():
"""一个执行较慢的函数"""
import time
time.sleep(1)
return "完成"
# 调用函数
result = slow_function()
print(result)
带参数的装饰器
python
# 带参数的装饰器
def repeat(n=1):
"""重复执行函数n次的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
results = []
for _ in range(n):
results.append(func(*args, **kwargs))
return results
return wrapper
return decorator
# 使用带参数的装饰器
@repeat(3)
def greet(name):
return f"你好,{name}!"
# 调用函数
results = greet("张三")
print(results) # 输出: ['你好,张三!', '你好,张三!', '你好,张三!']
类装饰器
python
# 类装饰器
class CountCalls:
"""计算函数调用次数的装饰器类"""
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"函数 {self.func.__name__} 已被调用 {self.count} 次")
return self.func(*args, **kwargs)
# 使用类装饰器
@CountCalls
def say_hello():
return "你好!"
# 调用函数
print(say_hello())
print(say_hello())
print(say_hello())
装饰器链
python
# 多个装饰器可以链式应用
@timer
@repeat(2)
def complex_operation(x, y):
import time
time.sleep(0.5)
return x + y
# 调用函数
result = complex_operation(10, 20)
print(result)
保留原函数元数据
使用functools.wraps
保留被装饰函数的元数据:
python
from functools import wraps
def logger(func):
@wraps(func) # 保留原函数的元数据
def wrapper(*args, **kwargs):
print(f"调用函数: {func.__name__}")
return func(*args, **kwargs)
return wrapper
@logger
def add(a, b):
"""将两个数相加"""
return a + b
# 查看函数元数据
print(add.__name__) # 输出: add(而不是wrapper)
print(add.__doc__) # 输出: 将两个数相加
3. 生成器(Generators)
生成器是一种特殊的迭代器,可以按需生成值,而不是一次性生成所有值,从而节省内存。
生成器函数
使用yield
语句创建生成器函数:
python
def count_up_to(max):
"""生成从1到max的数字"""
count = 1
while count <= max:
yield count
count += 1
# 使用生成器
counter = count_up_to(5)
print(next(counter)) # 输出: 1
print(next(counter)) # 输出: 2
# 在循环中使用生成器
for number in count_up_to(5):
print(number) # 输出: 1, 2, 3, 4, 5
生成器表达式
类似于列表推导式,但使用圆括号而不是方括号:
python
# 列表推导式(一次性生成所有值)
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
# 在循环中使用生成器表达式
for square in (x**2 for x in range(5)):
print(square) # 输出: 0, 1, 4, 9, 16
生成器的send方法
生成器可以通过send
方法接收外部值:
python
def echo_generator():
"""回声生成器:返回发送给它的值"""
response = yield "准备好接收值"
while True:
response = yield f"你说: {response}"
# 使用生成器的send方法
gen = echo_generator()
print(next(gen)) # 输出: 准备好接收值(启动生成器)
print(gen.send("你好")) # 输出: 你说: 你好
print(gen.send("Python很棒")) # 输出: 你说: Python很棒
生成器的应用:数据流处理
python
def read_large_file(file_path, chunk_size=1024):
"""分块读取大文件"""
with open(file_path, 'r') as f:
while True:
data = f.read(chunk_size)
if not data:
break
yield data
def grep(pattern, lines):
"""过滤包含指定模式的行"""
import re
pattern = re.compile(pattern)
for line in lines:
if pattern.search(line):
yield line
def count_words(lines):
"""计算每行的单词数"""
for line in lines:
yield len(line.split())
# 使用生成器进行数据流处理
def process_log_file(file_path, pattern):
# 读取文件
chunks = read_large_file(file_path)
# 将块分割成行
lines = (line for chunk in chunks for line in chunk.splitlines())
# 过滤包含指定模式的行
matching_lines = grep(pattern, lines)
# 计算单词数
word_counts = count_words(matching_lines)
# 计算总单词数
return sum(word_counts)
4. 迭代器(Iterators)
迭代器是实现了__iter__
和__next__
方法的对象,可以被用于for
循环。
创建自定义迭代器
python
class Countdown:
"""从n倒数到1的迭代器"""
def __init__(self, start):
self.start = start
def __iter__(self):
# 返回迭代器对象(这里是self)
return self
def __next__(self):
if self.start <= 0:
# 停止迭代
raise StopIteration
self.start -= 1
return self.start + 1
# 使用自定义迭代器
for i in Countdown(5):
print(i) # 输出: 5, 4, 3, 2, 1
迭代器与生成器的关系
生成器是一种特殊的迭代器,自动实现了__iter__
和__next__
方法:
python
# 使用生成器函数创建迭代器
def countdown(start):
while start > 0:
yield start
start -= 1
# 使用生成器创建的迭代器
for i in countdown(5):
print(i) # 输出: 5, 4, 3, 2, 1
5. 上下文管理器(Context Managers)
上下文管理器用于管理资源的获取和释放,通常与with
语句一起使用。
使用类创建上下文管理器
python
class FileManager:
"""文件管理上下文管理器"""
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
"""进入上下文时调用"""
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出上下文时调用"""
if self.file:
self.file.close()
# 返回True表示异常已处理,False表示异常需要传播
return False
# 使用自定义上下文管理器
with FileManager('example.txt', 'w') as f:
f.write('Hello, World!')
# 文件自动关闭
使用contextlib创建上下文管理器
python
from contextlib import contextmanager
@contextmanager
def open_file(filename, mode):
"""使用装饰器创建文件管理上下文管理器"""
try:
f = open(filename, mode)
yield f
finally:
f.close()
# 使用contextlib创建的上下文管理器
with open_file('example.txt', 'r') as f:
content = f.read()
print(content)
多个上下文管理器
python
# 同时使用多个上下文管理器
with open('input.txt', 'r') as in_file, open('output.txt', 'w') as out_file:
content = in_file.read()
out_file.write(content.upper())
6. 函数式编程
Python支持函数式编程范式,提供了许多函数式编程的特性。
lambda表达式
python
# 使用lambda创建匿名函数
add = lambda x, y: x + y
print(add(5, 3)) # 输出: 8
# 在排序中使用lambda
people = [
{'name': '张三', 'age': 30},
{'name': '李四', 'age': 25},
{'name': '王五', 'age': 35}
]
# 按年龄排序
people.sort(key=lambda person: person['age'])
print(people)
map, filter, reduce
python
# map: 对可迭代对象的每个元素应用函数
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares) # 输出: [1, 4, 9, 16, 25]
# filter: 过滤可迭代对象中的元素
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出: [2, 4]
# reduce: 将可迭代对象中的元素累积到单个值
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product) # 输出: 120 (1*2*3*4*5)
列表推导式、字典推导式和集合推导式
python
# 列表推导式
squares = [x**2 for x in range(10)]
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [0, 4, 16, 36, 64]
# 字典推导式
square_dict = {x: x**2 for x in range(5)}
print(square_dict) # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 集合推导式
square_set = {x**2 for x in range(5)}
print(square_set) # 输出: {0, 1, 4, 9, 16}
高阶函数
python
# 函数作为参数
def apply_operation(x, y, operation):
return operation(x, y)
result = apply_operation(5, 3, lambda x, y: x + y)
print(result) # 输出: 8
# 函数返回函数
def create_multiplier(factor):
def multiplier(x):
return x * factor
return multiplier
double = create_multiplier(2)
triple = create_multiplier(3)
print(double(5)) # 输出: 10
print(triple(5)) # 输出: 15
7. 元类(Metaclasses)
元类是创建类的类,可以用来控制类的创建过程。
基本元类
python
# 定义元类
class Meta(type):
def __new__(mcs, name, bases, attrs):
# 在类创建前修改类属性
attrs['added_by_meta'] = '我是由元类添加的属性'
print(f"创建类: {name}")
return super().__new__(mcs, name, bases, attrs)
# 使用元类
class MyClass(metaclass=Meta):
pass
# 实例化类
obj = MyClass()
print(obj.added_by_meta) # 输出: 我是由元类添加的属性
单例模式实现
python
class Singleton(type):
"""单例模式元类"""
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
# 使用单例元类
class Database(metaclass=Singleton):
def __init__(self):
print("数据库连接已创建")
# 测试单例
db1 = Database() # 输出: 数据库连接已创建
db2 = Database() # 没有输出,因为使用了相同的实例
print(db1 is db2) # 输出: True
8. 描述符(Descriptors)
描述符是实现了__get__
、__set__
或__delete__
方法的对象,用于自定义属性的访问行为。
基本描述符
python
class Validator:
"""验证属性值的描述符"""
def __init__(self, min_value=None, max_value=None):
self.min_value = min_value
self.max_value = max_value
self.name = None
def __set_name__(self, owner, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__.get(self.name)
def __set__(self, instance, value):
if self.min_value is not None and value < self.min_value:
raise ValueError(f"{self.name}不能小于{self.min_value}")
if self.max_value is not None and value > self.max_value:
raise ValueError(f"{self.name}不能大于{self.max_value}")
instance.__dict__[self.name] = value
# 使用描述符
class Person:
age = Validator(min_value=0, max_value=120)
def __init__(self, name, age):
self.name = name
self.age = age
# 测试描述符
person = Person("张三", 30)
print(person.age) # 输出: 30
try:
person.age = -5 # 引发ValueError
except ValueError as e:
print(e) # 输出: age不能小于0
9. 协程(Coroutines)与异步编程
Python 3.5+引入了async
/await
语法,支持异步编程。
基本协程
python
import asyncio
async def say_after(delay, what):
"""等待指定时间后打印消息"""
await asyncio.sleep(delay)
print(what)
async def main():
# 并发运行两个协程
task1 = asyncio.create_task(say_after(1, '你好'))
task2 = asyncio.create_task(say_after(2, 'Python'))
print('开始')
# 等待两个任务完成
await task1
await task2
print('结束')
# 运行协程
asyncio.run(main())
异步上下文管理器
python
import asyncio
class AsyncContextManager:
async def __aenter__(self):
print("进入异步上下文")
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("退出异步上下文")
return False
async def main():
async with AsyncContextManager() as manager:
print("在异步上下文中")
asyncio.run(main())
异步生成器
python
import asyncio
async def async_generator():
for i in range(5):
await asyncio.sleep(0.1)
yield i
async def main():
async for i in async_generator():
print(i)
asyncio.run(main())
10. 函数注解与类型提示
Python 3.5+引入了类型提示,可以提高代码的可读性和可维护性。
基本类型提示
python
def add(a: int, b: int) -> int:
"""将两个整数相加"""
return a + b
def greet(name: str) -> str:
"""向指定的人问候"""
return f"你好,{name}!"
def process_items(items: list[int]) -> list[int]:
"""处理整数列表"""
return [item * 2 for item in items]
使用typing模块
python
from typing import List, Dict, Tuple, Optional, Union, Callable
# 复杂类型提示
def process_data(
items: List[int],
mapping: Dict[str, int],
config: Optional[Dict[str, str]] = None
) -> Tuple[List[int], int]:
"""处理数据并返回结果元组"""
if config is None:
config = {}
result = [item * mapping.get(config.get('factor_key', 'default'), 1) for item in items]
total = sum(result)
return result, total
# 函数类型
def apply_function(func: Callable[[int, int], int], x: int, y: int) -> int:
"""应用函数到两个整数"""
return func(x, y)
类型检查
使用mypy等工具可以进行静态类型检查:
bash
# 安装mypy
pip install mypy
# 运行类型检查
mypy your_script.py
11. 练习:高级特性应用
练习1:使用装饰器实现缓存
python
import time
from functools import wraps
def memoize(func):
"""缓存函数结果的装饰器"""
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
# 创建可哈希的键
key = str(args) + str(sorted(kwargs.items()))
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return wrapper
@memoize
def fibonacci(n):
"""计算斐波那契数列的第n个数"""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 测试缓存效果
start = time.time()
result = fibonacci(35)
end = time.time()
print(f"结果: {result}")
print(f"第一次计算时间: {end - start:.6f} 秒")
start = time.time()
result = fibonacci(35) # 应该从缓存中获取
end = time.time()
print(f"结果: {result}")
print(f"第二次计算时间: {end - start:.6f} 秒")
练习2:使用生成器处理大文件
python
def find_lines_with_pattern(file_path, pattern):
"""在大文件中查找包含指定模式的行"""
import re
pattern_regex = re.compile(pattern)
with open(file_path, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, 1):
if pattern_regex.search(line):
yield line_num, line.strip()
def process_large_file(file_path, pattern):
"""处理大文件并打印匹配行"""
print(f"在文件 {file_path} 中查找模式 '{pattern}':")
for line_num, line in find_lines_with_pattern(file_path, pattern):
print(f"行 {line_num}: {line}")
# 使用示例
# process_large_file('large_log_file.txt', 'ERROR')
12. 今日总结
- 装饰器允许您修改函数或类的行为,而不需要直接修改其源代码
- 生成器是一种特殊的迭代器,可以按需生成值,节省内存
- 迭代器是实现了
__iter__
和__next__
方法的对象,可以被用于for
循环 - 上下文管理器用于管理资源的获取和释放,通常与
with
语句一起使用 - Python支持函数式编程范式,提供了lambda表达式、高阶函数等特性
- 元类是创建类的类,可以用来控制类的创建过程
- 描述符用于自定义属性的访问行为
- Python 3.5+引入了
async
/await
语法,支持异步编程 - 类型提示可以提高代码的可读性和可维护性
13. 第一周总结
恭喜您完成了Python学习的第一周!在这一周中,我们从Python基础入门开始,逐步学习了Python的数据结构、控制流、函数、面向对象编程、模块与包、文件操作与异常处理,最后是Python的高级特性。
您已经掌握了Python的核心概念和特性,为下一周的学习打下了坚实的基础。在第二周,我们将深入探讨Python的实际应用,包括Web开发、数据处理、测试与调试等方面,帮助您将Python知识应用到实际项目中。
明天我们将开始第二周的学习,首先介绍Python的Web开发框架Flask,帮助您快速构建Web应用。