python装饰器

参考:廖雪峰python教程

函数装饰器

函数装饰器:给函数添加功能,举例如下:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log
def now():
    print('2015-3-25')

now()
# 输出:
# call now():
# 2015-3-25

@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

所以now实际上已经是wrapper函数,调用now就是wrapper函数。在wrapper函数中首先打印了日志,然后调用了旧版的now函数并返回旧版的now的返回值。在这里log的作用是返回包装好的函数对象wrapper。

此时函数now的名字变为了wrapper,如下:

>>> now.__name__
'wrapper'

修改log函数,让名字变回now:

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

Python内置的functools.wraps执行wrapper.__name__ = func.__name__这样的代码,让名字变回now。

带参数的函数装饰器

如果log需要传入参数,那么代码修改如下:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')
def now():
    print('2015-3-25')

执行:

>>> now()
execute now():
2015-3-25

和两层嵌套的装饰器相比,3层嵌套的效果是这样的:

>>> now = log('execute')(now)

和两层嵌套的装饰器相比,都是返回包装好的wrapper函数对象。

用python装饰器修饰类

作用:给类添加一个函数。

def add_method(cls):
    def print_hello(self):
        print("Hello")
    cls.print_hello = print_hello
    return cls

@add_method
class MyClass:
    pass

obj = MyClass()
obj.print_hello()  # 输出 "Hello"

在上面的示例中,我们定义了一个名为 add_method 的装饰器函数,它接受一个类作为参数,并将一个名为 print_hello 的方法添加到该类中。然后我们使用 @add_method 装饰器将 MyClass 类传递给 add_method 函数,这样我们就在 MyClass 中添加了一个新的方法 print_hello。最后,我们实例化 MyClass 类,并调用 print_hello 方法来输出 "Hello"。

posted @ 2023-02-14 15:35  好人~  阅读(14)  评论(0编辑  收藏  举报