闭包函数 装饰器

1.闭包函数

  定义在函数内部的函数,引用了外部函数作用域的名字,主要满足上面的两点都叫做闭包函数。

def outer(x,y):
    def my_max():
        if x > y:
            return x
        return y
    return my_max
res = outer(32,53)  # res就是my_max函数的内存地址
print(res())  # 53
import requests
def outer(url):  # 给函数传参
    def my_get():
        response = requests.get(url)
        if response.status_code == 200:
            print(len(response.text))  # 92760
    return my_get
my_jd = outer('https://www.jd.com')
my_jd()

2.装饰器

  装饰器是用来给装饰对象添加新功能的工具

装饰器的开放封闭原则:

  开放:对扩展功能开放

  封闭:对原有功能的修改封闭

特点:

  1.不能改变装饰对象的源代码

  2.不改变被装饰对象的调用方式

装饰器应用场景

简单注册表

funcs = []
def register(func):
    funcs.append(func)
    return func
    
@register   # register(a)
def a():
    return 3
    
@register   # register(b)
def b():
    return 5
   
# 访问结果
result = [func() for func in funcs]
import time
print(time.time())  # 1562833711.367552 时间戳(距离1970.1.1  0点相差秒数)
time.sleep(3)  # cpu运行停止三秒
import time
def index():
    time.sleep(3)
    print('哈哈')  # 哈哈
def outer(func):  # func = index原始的index函数的内存地址
    def get_time():
        start = time.time()
        func()  # func() = index() 调用
        end = time.time()
        print('index run time:%s'%(end-start))  # index run time:3.000720500946045
    return get_time
index = outer(index)  # index指向get_time函数的内存地址
index()
import time
def index():
    time.sleep(3)
    print('哈哈')  # 哈哈
return 'index'
def login(name): time.sleep(1) print('%s'%name) # egon return 'login' def outer(func): # 最原始的login/index函数内存地址 def get_time(*args,**kwargs): # args = {'egon',} kwargs {} start = time.time() res = func(*args,**kwargs) # 最原始的login/index函数内存地址 end = time.time() print('index run time:%s'%(end-start)) # index run time:1.000943899154663 index run time:3.0001919269561768 return res return get_time login = outer(login) # 括号里的是最原始的login函数内存地址,前面的是变量名 res = login('egon') index = outer(index) # # 最原始的index函数内存地址 res = index()
import time
def outer(func):
    def get_time(*args,**kwargs):
        start = time.time()
        res = func(*args,**kwargs)
        end = time.time()
        print('index run time:%s'%(end-start))  # index run time:3.0018677711486816   index run time:1.0005810260772705   index run time:1.0004172325134277
        return res
    return get_time
@outer   # index = outer(index)
def index():
    time.sleep(3)
    print('哈哈')  # 哈哈
    return 'index'
@outer
def login(name):
    time.sleep(1)
    print('%s'%name)  # egon
    return 'login'
@outer
def home(*args,**kwargs):
    time.sleep(1)
    return'home'
index()
login('egon')
home()
装饰器模板
 outer(func):
    def inner(*args,**kwargs):
        print('执行被装饰函数之前能够做的操作')
        res = func(*args,**kwargs)
        print('执行被装饰之后,能够做的操作')
        return res
    return inner
认证装饰器
    执行函数index之前必须先输入用户名和密码 正确之后才能执行index,否则提示用户输入错误 结束程序
import
time user_dic = {'is_login':None} def login_auth(func): def inner(*args,**kwargs): if user_dic['is_login']: res = func(*args,**kwargs) return res else: username = input('please input your username>>>:').strip() password = input('please input your password>>>:').strip() if username == 'jason' and password == '123': user_dic['is_login'] = True res = func(*args,**kwargs) return res else: print('username or password error') return inner @login_auth def index(name): time.sleep(1) print('%s is dsb'%name) # egon is dsb return 666 @login_auth def home(): time.sleep(1) print('home') # home return 999 index('egon') print(index) # <function login_auth.<locals>.inner at 0x000002811B4A8A60> home() print(home) # <function login_auth.<locals>.inner at 0x000002811B4A8B70>
1.无参装饰器
    from functools import wraps
    def outter(func):
        @wraps(func)  # index = wraps(inner)
        def inner(*args,**kwargs):  # * **在形参中使用
            # 执行被装饰函数之前你可以做的操作
            res = func(*args,**kwargs)  # * **在实参中使用
            # 执行被装饰函数之后你可以做到操作
            return res
        return inner
    @outter   # index = outter(index)
    def index(username,*args,**kwargs):
        """index注释"""
        pass
    print(index)
2.有参装饰器(最复杂就三层)
def wrappers(data):
    # data = 'file'
    def outter(func):
        def inner(*args,**kwargs):
            if data == 'file':
                # 执行被装饰函数之前你可以做的操作
                res = func(*args,**kwargs)  # * **在实参中使用
                # 执行被装饰函数之后你可以做到操作
                return res
        return inner
    return outter
posted @ 2019-07-12 14:35  大爷灰  阅读(138)  评论(0编辑  收藏  举报