文章6:高级Python特性
目标
掌握Python的高级功能,包括装饰器、生成器、上下文管理协议和元类,以提升代码的灵活性和效率。
一、装饰器(Decorators)
1. 基础语法与作用
装饰器用于在不修改原函数代码的情况下,动态添加功能或修改行为。核心是闭包和高阶函数。
示例:日志记录装饰器
import functools
def log_decorator(func):
@functools.wraps(func) # 保留原函数元信息
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"Result: {result}")
return result
return wrapper
@log_decorator
def add(a, b):
return a + b
add(3, 5) # 输出日志并返回8
2. 带参数的装饰器
通过嵌套函数传递装饰器参数。
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet():
print("Hello!")
greet() # 输出"Hello!"三次
3. 类装饰器
通过实现__call__
方法,使类可作为装饰器。
class CounterDecorator:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"Called {self.count} times")
return self.func(*args, **kwargs)
@CounterDecorator
def say_hello():
print("Hello")
say_hello() # 输出"Called 1 times"和"Hello"
练习
实现一个计时器装饰器,记录函数执行时间。
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Execution time: {end - start:.4f} seconds")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
slow_function() # 输出执行时间约1秒
二、生成器(Generators)与迭代器(Iterators)
1. 迭代器协议
迭代器必须实现__iter__()
和__next__()
方法。
class Counter:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.max:
raise StopIteration
self.current += 1
return self.current
for num in Counter(5):
print(num) # 输出1到5
2. 生成器
通过yield
语句生成值,自动实现迭代器协议。
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(5):
print(num) # 输出0, 1, 1, 2, 3
3. 生成器表达式
sum_of_evens = sum(x for x in range(10) if x % 2 == 0) # 计算0-9偶数和
练习
编写一个生成器,逐行读取大文件(避免内存溢出)。
def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()
for line in read_large_file("data.txt"):
process(line)
三、上下文管理协议(with语句)
1. 基础用法
通过__enter__
和__exit__
方法管理资源(如文件、网络连接)。
class ManagedFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'w')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
with ManagedFile("output.txt") as f:
f.write("Hello, context manager!")
2. 使用contextlib
简化实现
from contextlib import contextmanager
@contextmanager
def managed_file(filename):
try:
f = open(filename, 'w')
yield f
finally:
f.close()
with managed_file("output.txt") as f:
f.write("Using contextlib!")
练习
实现一个计时器上下文管理器,自动记录代码块的执行时间。
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f"Elapsed time: {self.end - self.start:.4f} seconds")
with Timer():
time.sleep(0.5) # 输出约0.5秒
四、元类(Metaclasses)简介
1. 什么是元类?
元类是创建类的类,控制类的创建过程。默认元类是type
。
2. 自定义元类
class MyMeta(type):
def __new__(cls, name, bases, attrs):
# 修改类属性
attrs['is_custom'] = True
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
print(MyClass.is_custom) # 输出True
3. 典型应用场景
- 单例模式:确保一个类只有一个实例。
- 自动注册子类:如框架中的插件系统。
class AutoRegisterMeta(type):
registry = {}
def __new__(cls, name, bases, attrs):
new_class = super().__new__(cls, name, bases, attrs)
cls.registry[name] = new_class
return new_class
class Plugin(metaclass=AutoRegisterMeta):
pass
class EmailPlugin(Plugin):
pass
print(AutoRegisterMeta.registry) # {'EmailPlugin': <class '__main__.EmailPlugin'>}
练习
实现一个元类,禁止子类化(即类不能被继承)。
class NoInheritMeta(type):
def __new__(cls, name, bases, attrs):
for base in bases:
if isinstance(base, NoInheritMeta):
raise TypeError("Cannot inherit from singleton class")
return super().__new__(cls, name, bases, attrs)
class Singleton(metaclass=NoInheritMeta):
pass
class Child(Singleton): # 触发错误
pass
总结
掌握这些高级特性后,你可以:
- 装饰器:优雅地复用代码,如日志、权限验证。
- 生成器:高效处理大数据或惰性计算。
- 上下文管理:安全管理资源,避免泄漏。
- 元类:控制类的创建,实现设计模式。
继续探索这些工具,你的Python代码将更加简洁、高效且灵活!