8Learning Python(第5版)

高级主题

装饰器与描述符

装饰器属性管理描述符元类设计模式

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第8章:高级主题(Advanced Topics)

一、导读

1.1 本章学习目标

第8章讲解 Python 的高级特性:装饰器、描述符、元类和设计模式。

1.2 为什么第八章如此重要

这些高级特性让你能够编写更强大、更灵活的 Python 代码。

1.3 核心问题引导

装饰器的高级用法有哪些?

描述符如何工作?

元类是什么?何时使用?

Python 中如何实现常见设计模式?


二、核心概念详解

8.1 高级装饰器

python
import functools

# 带参数的装饰器
def repeat(num_times):
    def decorator(func):
        @functools.wraps(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}!")

# 类装饰器
class CountCalls:
    def __init__(self, func):
        functools.update_wrapper(self, func)
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call {self.count} of {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

8.2 描述符

python
class Validator:
    def __init__(self, min_value=None, max_value=None):
        self.min_value = min_value
        self.max_value = max_value
    
    def __set_name__(self, owner, name):
        self.name = name
    
    def __get__(self, obj, objtype=None):
        return getattr(obj, f'_{self.name}', None)
    
    def __set__(self, obj, value):
        if self.min_value is not None and value < self.min_value:
            raise ValueError(f"{self.name} must be >= {self.min_value}")
        if self.max_value is not None and value > self.max_value:
            raise ValueError(f"{self.name} must be <= {self.max_value}")
        setattr(obj, f'_{self.name}', value)

class Product:
    price = Validator(min_value=0)
    quantity = Validator(min_value=0, max_value=1000)
    
    def __init__(self, price, quantity):
        self.price = price
        self.quantity = quantity

8.3 元类

python
# 元类控制类的创建
class SingletonMeta(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=SingletonMeta):
    def __init__(self):
        self.connection = "connected"

db1 = Database()
db2 = Database()
print(db1 is db2)  # True

# 使用 __init_subclass__(更简单)
class PluginBase:
    plugins = []
    
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        PluginBase.plugins.append(cls)

8.4 设计模式

python
# 观察者模式
class EventEmitter:
    def __init__(self):
        self._listeners = {}
    
    def on(self, event, callback):
        self._listeners.setdefault(event, []).append(callback)
    
    def emit(self, event, *args, **kwargs):
        for callback in self._listeners.get(event, []):
            callback(*args, **kwargs)

# 策略模式
class Sorter:
    def __init__(self, strategy):
        self.strategy = strategy
    
    def sort(self, data):
        return self.strategy(data)

# 工厂模式
class AnimalFactory:
    @staticmethod
    def create_animal(type):
        if type == "dog":
            return Dog()
        elif type == "cat":
            return Cat()
        raise ValueError(f"Unknown animal: {type}")

三、实战案例

8.1 缓存装饰器

python
def memoize(func):
    cache = {}
    @functools.wraps(func)
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

@memoize
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # 瞬间完成

四、本章小结

高级装饰器支持参数和类形式。描述符实现属性验证。元类控制类的创建。Python 可以灵活实现各种设计模式。


五、思考与练习

带参数的装饰器如何实现?

描述符的作用是什么?

元类在什么场景下使用?

Python 中如何实现单例模式?

如何编写可复用的装饰器?


8/8高级主题
0%