装饰器总结

装饰器总结
1. 闭包。
闭包定义:在函数嵌套的前提下,内层函数调用外层函数的变量,外层函数返回内层函数的引用。
闭包作用: 可以保存外部函数的变量,不会随着外部函数调用而销毁。
注意点:由于闭包引用了外部函数的变量,则外部函数的变量没有及时释放,消耗内存。

2.装饰器
目的:在不改变函数源代码和调用方式的前提下,给函数添加新的功能。
实质:闭包函数。内层函数调用外层函数的函数。就是给已有函数增加额外的功能函数。

装饰器的种类:
1 .最简单装饰器
比如添加一个登录功能

def logging(fn):
	def inner():
		print('logging..........')
		fn()
	return inner

def comment():
  print('make comment')
 
comment = logging(comment)
comment()

简单吧? 就是这么简单。也可以用语法糖来装饰

def logging(fn):
	def inner():
		print('logging..........')
		fn()
	return inner

@logging
def comment():
  print('make comment')
 
comment()

@logging 就等价于 comment = logging(comment)

再来一个应用场景吧。比如给函数添加一个计算执行时间的功能
我们来写一个这样的装饰器

import time


def CalculatingTime(fn):
    def inner():
        begin = time.time()
        fn()
        end = time.time()
        print('use time: %f' %(end - begin))

    return inner


@CalculatingTime
def Print1to100000():
    for i in range(100000):
        print(i)


Print1to100000()
  1. 装饰带有参数的函数
def logging(fn):
    def inner(a, b):
        print('logging.....')
        fn(a, b)

    return inner


@logging
def Calculating(a, b):
    result = a + b
    print(result)


Calculating(1, 2)

就是函数带了个参数,直接在内层函数带上就好了

3.装饰带有返回值的函数

def logging(fn):
    def inner(a, b):
        print('logging.....')
        result = fn(a, b)
        return result
    return inner


@logging
def Calculating(a, b):
    result = a + b
    return result

result = Calculating(1, 2)
print(result)

是不是有点疑问啊?明明Calculating函数里面已经返回了,为什么在装饰器内层函数里面还要再返回一遍呢,因为被装饰的函数,装饰完实际上就是内层函数,不再是原来的Calculating函数了,要想装饰完也能返回result, 就得在内层函数再返回result, 不然是不会有返回值的。所以要在内层函数得到Calculating函数的返回结果然后再返回。

4.装饰带有不定长参数的函数

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

@logging
def Calculating(*args, **kwargs):
	result =0 
	for value in args:
		result += value
	for value in kwargs.values():
		result +=value
	print(result)

Cauculating(1, 2, a=3, b=4)

也没什么。就是把参数换成不定长。一个元组传参,一个字典传参。字典循环的时候记得要加values

5.通用装饰器
顾名思义,就是把之前几个功能综合一下。
还是登录功能装饰器

def logging(fn):
    def inner(*args, **kwargs):
        print('logging..........')
        result = fn(*args, **kwargs)
        return result

    return inner


@logging
def Calculating(*args, **kwargs):
    result = 0
    for value in args:
        result += value
    for value in kwargs.values():
        result += value
    return result


# 再写一个函数体现装饰器的通用性
@logging
def subCalculating(a, b):
    result = a - b
    print(result)


result = Calculating(1, 2, a=3, b=4)
print(result)
subCalculating(4, 2)

来写一下通用装饰器的语法格式吧:

def outer(fn):
	def inner(*args, **kwargs):
		print('do something before fn')
		result = fn(*args, **kwargs)
		print('do something after fn')
		return result
	return inner

6.多个装饰器装饰函数。
知道一点:装饰顺序由下到上,执行顺序由上到下,就不具体去写了。

7.带有参数的装饰器
在装饰器外面再包裹一个函数,让最外面的函数接受参数, 返回的是装饰器。三层嵌套。

def logging(flag):
    def decorator(fn):
        def inner(*args, **kwargs):
            print('logging........')
            if flag == '+':
                print('add..........')
            if flag == '-':
                print('sub..........')
            result = fn(*args, **kwargs)
            return result
        return inner
    return decorator


@logging("+")
def add(a, b):
    result = a + b
    return result


@logging("-")
def sub(a, b):
    result = a - b
    return result


result = add(1, 2)
print(result)

result = sub(2, 1)
print(result)

8.类装饰器
通过定义一个类来装饰函数。利用 __call__方法实现调用实例对象可以像调用函数一样调用。

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

    def __call__(self, *args, **kwargs):
        print('logging..........')
        self.fn()


def comment():
    print('make comment.....')


comment = logging(comment)
comment()


@logging
def comment():
    print('make comment.....')


comment()

9.带参数的类装饰器

class logging(object):
    def __init__(self, flag):
        self.flag = flag

    def __call__(self, fn):
        def inner(*args, **kwargs):
            print('logging..........')
            if self.flag == '+':
                print('add........')
            elif self.flag == '-':
                print('sub.........')
            result = fn(*args, **kwargs)
            return result
        return inner

@logging("+")
def add(a, b):
    result = a + b
    return result


@logging("-")
def sub(a, b):
    result = a - b
    return result


result = add(1, 2)
print(result)

result = sub(2, 1)
print(result)	
	

在init函数里面传入参数。
先总结到这里吧。以后再慢慢更新一些例子。装饰器在flask里面用的比较多,必须牢牢掌握!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值