一以贯之

python: 装饰器详解

一、什么是闭包?

 闭包就是内层函数对外层函数(非全局)变量的引用

 

如何判断内层函数   __closure__     cell就是闭包

 

闭包: 当函数开始执行时,如果遇到了闭包,他有一个机制

  : 会永远开辟一个内存空间,将闭包中的等值放入其中,不会随着函数的执行完毕而消失

name = 'jin'
def wrapper():
    name1 = 'king'
    def inner():
        print(name)
        print(name1)
    inner()
    print(inner.__closure__)

wrapper()

#jin
#king
#(<cell at 0x00000200CC6FE858: str object at 0x00000200CC4CFF10>,)

 

二、装饰器

1.什么是装饰器?

语法糖@
在不改变原函数的执行情况下,为原函数添加新的功能
 
输入: 被装饰的函数名
输出: 内部函数名

 

2装饰器~~~~

 

2.1无参数的装饰器

import time
def timer(func):
    def inner():
        befor = time.time()
        ret = func()
        after = time.time()
        print("this is use time {}".format(after-befor))
        return inner
    return inner
@timer
def func1():
    for i in range(10):
        time.sleep(0.1)
        print(i)

func1()

#this is use time 1.0047006607055664

 

 

2.带参数的装饰器

 2.1

import time
def timer(func):
    def inner(*args,**kwargs):
        befor = time.time()
        ret = func(*args, **kwargs)
        after = time.time()
        print("this is use time {}".format(after-befor))
        return inner
    return inner
@timer
def func1(x):
    for i in range(x):
        time.sleep(0.1)
        print(i)

func1(10)

 

2.2

def test(flag):
    def wrapper(func):
        flag1 = 0

        def inner(*args,**kwargs):
            try:
                ret = func(*args,**kwargs)

            except Exception as e:
                print(e)
                nonlocal flag1
                while flag1 < int(flag):
                    print(flag1)
                    flag1 += 1
                    inner()
        return inner

    return wrapper






@test(3)
def func(*args):
    x = "1"
    y = x + 2
    return y

func()

 

 

2.3实现缓存

注: 不加functools也可以实现

 

# from functools import wraps
def wrapper(func):
    cache = {}
    # print(cache)
    # @wraps(func)
    def inner(*args):
        if args not in cache:
            print("ok")
            cache[args] = func(*args)
        print(func.__doc__)
        print(func.__name__)
        print(cache)
        return cache[args]


    return inner

@wrapper
def sum(x):
    '''
    求和
    :param x:
    :return:
    '''
    y = x+x
    return y
@wrapper
def sub(x):
    '''
    求差
    :param x:
    :return:
    '''
    y = x-1
    return y


x = sum(1)
print(x)
print('____________________')

z = sum(1)
print(z)
print('____________________')

z = sum(2)
print(z)
print('____________________')


y = sub(1)
print(y)
print('____________________')
y = sub(2)
print(y)
print('____________________')

 

 

2.3多个装饰器装饰一个函数

 

def wrapper1(func):
    def inner1(*args,**kwargs):  # func = f函数名
        print('wrapper1,befor func')#2
        func()                      #3
        print('wrapper1,after func') #4

    return inner

def wrapper2(func):  # func == inner1
    def inner2(*args,**kwargs):
        print('wrapper2, befor func') #1
        func()
        print('wrapper2, after func')   #5
    return inner

@wrapper2
#f = wrapper2(f) 里面的f == inner1 外面的 f == inner2 @wrapper1 #f = wrapper1(f)  里面的f == 函数名f, 外面的f == inner1 def f(): print('in f') f()

 

posted on 2019-05-04 09:12  凡夫or俗子  阅读(181)  评论(0)    收藏  举报