CodeGym /课程 /Python SELF ZH /装饰器的威力

装饰器的威力

Python SELF ZH
第 14 级 , 课程 2
可用

6.1 类方法的装饰器

装饰器也可以用于类的方法。重要的是要记住,对于类的方法,需要正确传递 selfcls 参数。

关于类的细节我们还没学,不过我希望你知道装饰器有这样的功能。


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"调用方法 {func.__name__}")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

解释

装饰器 (log_method_call): 这个装饰器接收方法 func 并返回一个新的函数 wrapper,它在调用方法前打印一条消息。

带有装饰器的方法类 (say_hello): 方法 say_hello 被装饰器 log_method_call 包裹,从而在调用时添加了额外的行为。

输出:


调用方法 say_hello
Hello from MyClass!

6.2 多个装饰器

你可以为一个函数使用多个装饰器,依次叠加。装饰器的应用顺序与声明顺序相反。


def decorator1(func):
    def wrapper():
        print("装饰器 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("装饰器 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

解释

装饰器 (decorator1 和 decorator2): 这些装饰器在调用函数 func 前添加自定义消息。

具有装饰器的函数 (say_hello): 函数 say_hello 被两个装饰器包裹,首先应用 decorator2,然后 decorator1

输出:


# 装饰器 1
# 装饰器 2
Hello!

6.3 内置装饰器

Python 提供了一些内置装饰器用于标准任务,比如静态方法、类方法和属性。

@staticmethod

装饰器 @staticmethod 用于创建静态方法,该方法不需要类的实例即可调用。


class MyClass:
    @staticmethod
    def static_method():
        print("这是一个静态方法。")
        
MyClass.static_method()

@classmethod

装饰器 @classmethod 用于创建类方法,该方法接受类(而不是实例)作为第一个参数。


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"这是类方法 {cls.__name__}。")
        
MyClass.class_method()

@property

装饰器 @property 用于创建属性的 getter、setter 和 deleter。


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # 输出: 10
obj.value = 20
print(obj.value)  # 输出: 20

这些是内置的装饰器,Python 解释器确保它们能正确工作。

6.4 装饰器的使用示例

日志记录

装饰器可以用来记录函数和方法的调用。


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"调用函数 {func.__name__} 参数为 {args} 和 {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

访问控制

装饰器可以用来控制对函数和方法的访问。


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("用户未经认证。")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("用户资料")
        
user = User(is_authenticated=True)
user.view_profile()  # 成功调用
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: 用户未经认证。

缓存

装饰器可以用来缓存函数的结果。


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION