装饰器核心

第一个装饰器 

        在Python中的装饰器可以提供一些额外的功能。装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象。装饰器用于一下场景,如:插入日志、性能测试、事务处理、缓存、权限校验等。

def simple_decorator(func):
    def wrapper():
        print("函数调用前")
        func()
        print("函数调用后")
    return wrapper

@simple_decorator
def say_hello():
    print("Hello")

say_hello()

"""
运行结果:
函数调用前
Hello
函数调用后
"""
import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"函数 {func.__name__} 的执行时间为: {end_time - start_time} 秒")
        return result
    return wrapper

@timer_decorator
def say_hello(name):
    time.sleep(1)
    print(f"Hello, {name}")

say_hello("Python")

"""
运行结果:
Hello, Python
函数 say_hello 的执行时间为: 1.0007023811340332 秒
"""

多个装饰器

        有时候需要多个装饰器修饰一个函数。

import time

def simple_decorator(func):
    def wrapper():
        print("函数调用前")
        func()
        print("函数调用后")
    return wrapper

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"函数 {func.__name__} 的执行时间为: {end_time - start_time} 秒")
        return result
    return wrapper

@timer_decorator
@simple_decorator
def say_hello():
    time.sleep(1)
    print("Hello")

say_hello()

"""
运行结果:
函数调用前
Hello
函数调用后
函数 wrapper 的执行时间为: 1.008784532546997 秒
"""

 当有多个装饰器时,离函数近的装饰器会优先被执行。这里的执行顺序是decorator2 > decorator1

@decorator1
@decorator2
def function():
    pass

这种顺序可以通过将装饰器看作是函数调用来理解

function = decorator1(decorator2(function))

带参数的装饰器

def decorator_with_args(decorator_arg1, decorator_arg2):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"装饰器参数: {decorator_arg1}, {decorator_arg2}")
            func(*args, **kwargs)
        return wrapper
    return decorator

@decorator_with_args("Hello", "World")
def greet(name):
    print(f"Hello, {name}")

greet("Python")

"""
运行结果:
装饰器参数: Hello, World
Hello, Python
"""

wraps装饰器

        functool.wraps是Python的内置装饰器,用于在定义装饰器时保留原始函数的元信息(如函数名、文档字符串等)。如果不适用functools.wraps,装饰后的函数将丢失这些元信息。

def my_decorator(func):
    # @wraps(func)
    def wrapper(*args, **kwargs):
        """wrapper函数"""
        print("Before call")
        result = func(*args, **kwargs)
        print("After call")
        return result
    return wrapper

@my_decorator
def greet(name):
    """Greet函数"""
    print(f"Hello, {name}")

greet("CursorBot")
print(greet.__name__)
print(greet.__doc__)

"""
输出结果:
Before call
Hello, CursorBot
After call
wrapper
wrapper函数
"""

将注释掉的@wraps(func)复原后

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """wrapper函数"""
        print("Before call")
        result = func(*args, **kwargs)
        print("After call")
        return result
    return wrapper

@my_decorator
def greet(name):
    """Greet someone."""
    print(f"Hello, {name}")

greet("CursorBot")
print(greet.__name__)
print(greet.__doc__)

"""
运行结果:
Before call
Hello, CursorBot
After call
greet
Greet函数
"""

内置装饰器

property装饰器、staticmethod装饰器、classmethod装饰器

        property装饰器用于类中的函数,可以让我们像访问属性一样来获取一个函数的返回值。

        staticmethod装饰器同样用于类中的方法,这表示这个方式是一个静态方法,意味着该方法可以直接被调用无需实例化,同时也意味着它没有self参数,也无法访问实例化后的对象。

        classmethod是一个类方法,无需实例化,没有self参数。与staticmethod的区别在于它会接收一个指向类本身的cls参数。

class User:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def tell_name(self):
        return f"我叫{self.name}"

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

    @classmethod
    def say_Hi(cls):
        print(f"我是{cls.__name__}")
        print("Hi!")

if __name__ == '__main__':
    u1 = User("竹筒饭","18")
    print(u1.tell_name)

    User.say_hello()

    User.say_Hi()

"""
运行结果:

我叫竹筒饭
Hello!
我是User
Hi!
"""

类装饰器

类能实现装饰器功能,是由于当调用一个对象时,实际上调用的是它的__call__方法

class classDecorator():
    def __init__(self,func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("class Decorator")
        return self.func(*args, ** kwargs)


@classDecorator     # 相当于myfunc = classDecorator(myfunc)
def myfunc():
    print("my func")


if __name__ == '__main__':
    myfunc()


"""
运行结果:
class Decorator
my func
"""

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值