python笔记-装饰器

一、装饰器

python的装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。简单的说装饰器就是一个用来返回函数的函数

  1. 它能使函数的功能得到扩充,而同时不用修改函数本身的代码。
  2. 它能够增加函数执行前、执行后的行为,而不需对调用函数的代码做任何改变。

执行流程:在执行装饰器修饰的函数时,python解释器会将被装饰的函数当成参数传入装饰器函数中。将装饰器函数的返回值当成函数调用,被装饰函数的参数继续传递给装饰器函数的返回值。

二、函数装饰器

2.1 简单装饰器

以下代码, 是一个简单的装饰器

def func(f):
    print("%s执行结果" % f.__name__, end=": ")
    f()


def test():
    print("hello world")


func(test)
  1. func函数是装饰器函数
  2. test函数是被装饰函数
  3. 功能就是, 在不修改test函数的代码前提下, 增加一个输出函数名的功能.

2.2 装饰器

不带参数的装饰器

def decorator(func):
    def run(*args, **kwargs):
        print("函数%s执行结果: %d" % (func.__name__, func(args[0], args[1])))
    return run


@decorator
def mul(a, b):
    return a * b


mul(3, 4)  # 输出 函数mul执行结果: 12
  1. @运算符: 标记装饰器
  2. 装饰器执行机制:
    1. 被装饰的函数mul在调用时, 被解释器检查到有装饰器标志.
    2. 不会立即执行mul函数, 解释器会将mul函数当参数, 传递到装饰器函数decorator内部.
    3. 由装饰器函数的内部run函数对mul函数进行装饰.
    4. 当完成修饰函数mul后, 装饰器函数会将其内部函数run返回, 并当成函数进行调用. mul函数的参数, 则会传递到装饰器函数返回的run函数.

示例
使用装饰器, 要求打印出是哪个函数执行的结果

def func(f):
    def run():
        print("%s执行结果" % f.__name__, end=": ")
        f()
    return run


@func
def test():
    print("hello world")


# func(test)
test()

带参数的装饰
实现一个计算功能, 要求可以查看是谁调用的这个计算功能

def set_name(name):
    def decorator(func):
        def run(*args, **kwargs):
            print("%s调用计算函数%s执行结果为: %.2f" %(name, func.__name__, func(args[0], args[1])))
        return run
    return decorator


@set_name("小芳")
def div(a, b):
    return a / b


div(3, 2)
  1. set_name("小芳"): 因为对set_name进行调用, set_name函数已被执行. 返回值是decorator函数
  2. 可以将@set_name('小芳')理解为@decorator. 这样就可以将被装饰函数传入到内层函数

三、内置装饰器

  1. property: 属性装饰
  2. staticmethod: 静态方法装饰
  3. classmethod: 类方法装饰器
class Cls:

    @property  # 以属性形式调用方法
    def test01(self):
        return '以属性形式调用方法'

    @staticmethod  # 不会自动传入self
    def test02():
        print('不会自动传入实例')

    @classmethod
    def test03(cls):
        print('将类自动传入')

四、类装饰

class Decorator:
    def __init__(self, fun):
        self.fun = fun

    def __call__(self, *args, **kwargs):
        print("函数%s执行结果: %d" % (self.fun.__name__, self.fun(args[0], args[1])))


@Decorator
def minus(a, b):
    return a - b


minus(20, 3)
  1. 装饰器函数的返回值, 当成了函数继续调用, 被装饰函数的参数就传递给了装饰器函数的返回值
  2. 使用类装饰器, 必须定义 __init____call__两个方法
    1. __init__方法用于接收被装饰的函数名
    2. __call__方法用于编写修饰 被装饰函数的逻辑, 也即是接受被装饰函数的参数
原文地址:https://www.cnblogs.com/duyupeng/p/13171853.html