千字长文讲解python装饰器

1.装饰器是一个用于封装函数或类的代码的工具。它显式的将封装器应用到函数或类上,从而使它们选择加入到装饰器的功能中【装饰器不仅可以装饰函数,也可以装饰类】。
2.对于①在函数运行前处理常见前置条件(例如确认授权),或②在函数运行后确保清理(例如输出清除或异常处理)装饰器都非常有用
a.①

def decorator_func():
    // do something
    decorated_func()

b.②

def decorator_func():
    decorated_func()
    // do something

3.对于处理已经被装饰的函数或类本身,装饰器也很有用。例如,装饰器可以将函数注册到信号系统?,或者注册到Web应用程序的URI注册表中。
4.究其核心而言,装饰器就是一个可以接受调用也可以返回调用的调用。装饰器无非就是一个函数(或调用,如有_call_method_方法的对象),该函数接受被装饰的函数作为其位置参数。装饰器通过使用该参数来执行某些操作,然后返回原始参数或一些其他的调用(大概以这种方式与编译器交互)
5.由于函数在python中是一级对象?,因此它们能够像其他对象一样被传递到另一个函数。装饰器就是接受另一个函数作为参数,并用其完成一些操作的函数。
6.@decorator_func是在Python 2.5引入的
7.对某个可调用函数,可以使用多个装饰器。如果通过@语法使用多个装饰器,就可以按照自底向上的顺序来应用它们。
首先发生的是解释器创建add函数,然后应用decorated_by装饰器。该装饰器返回了一个可调用函数,该函数被发送给also_decorated_by装饰器,also_decorated_by也做了同样的事情,接下来结果被赋给add函数。

@also_decorated_by
@decorated_by
def add(x, y):
    return x + y

8.如果要使一个类上的方法不需要这个类的实例,可以使用@classmethod或@staticmethod。
9.mock模块允许使用@mock.patch或@mock.patch.object作为装饰器。
10.Celery(常见的Python任务运行工具)使用复杂的@task装饰器来标识函数是否为异步任务。
11.编写装饰器的时机
a.附加功能
b.数据的清理或添加
c.函数注册
12.装饰器通常接受被装饰的可调用函数作为唯一参数,并且返回一个可调用函数
13.示例
a.函数注册表
b.执行时封装代码
i.functools.wraps
14.常见装饰器写法

def outer(func):
    def inner():
        print('do something here')
        func()
    return inner


def my_func():
    print('this is my_func')


my_func = outer(my_func)

my_func()

'''
do something here
this is my_func
'''

15.装饰器的作用:在不改变已有函数的源代码的情况下,给函数增加新的功能
16.装饰器的功能特点
a.不修改已有函数的源代码
b.给已有函数增加额外的功能
17.装饰器符合了开发中的封闭开放原则
18.装饰器的本质是闭包
19.装饰器就是把一个函数当做参数传递给闭包中的外部函数,同时在内部函数中使用这个函数,并给它添加新的功能
20.装饰带有参数的函数:让inner函数的参数和被装饰函数的参数保持一致

def logging(fn):
    def inner(a, b):
        res = fn(a, b)
        print(res)
    return inner


@logging
def sum_num(a, b):
    res = a + b
    return res


sum_num(1, 2)
'''
3
'''

21.装饰带有返回值的函数:在inner函数中返回被装饰函数的返回值即可

def logging(fn):
    def inner(a, b):
        res = fn(a, b)
        return res
    return inner


@logging
def sum_num(a, b):
    res = a + b
    return res


print(sum_num(1, 2))
'''
3
'''
  1. 装饰带有不定长参数的函数
def logging(fn):
    def inner(*args, **kwargs):
        fn(*args, **kwargs)
    return inner


@logging
def sum_num(*args, **kwargs):
    print(args, kwargs)


sum_num(1, 2, 3, age=18)

'''
(1, 2, 3) {'age': 18}
'''

23.通用装饰器

 def logging(fn):
    def inner(*args, **kwargs):
        return fn(*args, **kwargs)
    return inner


@logging
def sum_num(*args, **kwargs):
    print(args, kwargs)


sum_num(1, 2, 3, age=18)

'''
(1, 2, 3) {'age': 18}
'''
  1. 带有参数的装饰器
    a.装饰器的外部函数只能接受被装饰的函数这一个参数
    b.如果需要给装饰器传参数需要在装饰器外部再增加一个函数
def logging(flag):
    def decorator(fn):
        def inner(num1, num2):
            print(flag, fn(num1, num2))
        return inner
    return decorator


@logging('abc')
def add(a, b):
    return a + b


add(1, 2)

'''
abc 3
'''

25.__call__方法的使用
a.如果一个类实现了__call__方法,那么这个类创建的对象就是一个可调用对象,可以像函数一样进行调用

class Check(object):
    def __call__(self, *args, **kwargs):
        print('this is __call__ function')


c = Check()
c()
'''
this is __call__ function
'''

26.类装饰器

class Check(object):
    def __init__(self, fn):
        self.__fn = fn

    def __call__(self, *args, **kwargs):
        print('验证')
        self.__fn()


@Check
def comment():
    print('发表评论')


comment()

'''
验证
发表评论
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值