闭包函数和装饰器
闭包函数
打破层级关系,把局部变量拿到全局使用
使用参数的形式:
def func(x):
    print(x)
func(1)
1
包给函数:
def outter(x):
    def inner(x):
        print(x)
    return inner
f = outter(1)
f()
1
闭包函数的应用
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得该函数无论在何处调用,优先使用自己外层包裹的作用域。
应用领域:延迟计算、爬虫领域。
import requests
def outter(url):
    def get():
        response = requests.get(url)
        print(f'给你网址:{url}')
    return get
baidu = outter('https://www.baidu.com')
baidu()
装饰器
装饰器本质上其实也是一个函数,只不过该函数的功能是用来为其他函数添加额外的功能,并且改变功能的时候不改变原来的调用方式,并且不改变原来函数的代码。
import time
def index():
    print('welcome to index')
    time.sleep(1)
    
def time_count(func):
    def wrapper():
        start = time.time()
        func()
        end = time.time()
        print(end-start)
    return wrapper
index = time_count(index)
index()
welcome to index
1.0038220882415771
完善装饰器
上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),以此如果原始的index()有返回值的时候,wrapper()函数的返回值应该和index()的返回值相同,也就是说,我们需要同步原始的index()和wrapper()方法的返回值。
import time
def index():
    print('welcome to index')
    time.sleep(1)
    return 123
def time_count(func):
    def wrapper():
        start = time.time()
        res = func()
        end = time.time()
        print(end-start)
        return res
    return wrapper
index = time_count(index)
res = index()
print(res)
welcome to index
1.0050289630889893
123
如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可。
import time
def time_count(func):
    def wrapper(*args,**kwargs):
        start = time.time()
        res = func(*args,**kwargs)
        end = time.time()
        print(end-start)
        return res
    return wrapper
def index():
    print('welcome to index')
    time.sleep(1)
    return 123
def home(name):
    print(f'welcome {name} to home page')
    time.sleep(1)
    return name
home = time_count(home)
res = home('nick')
print(res)
welcome nick to home page
1.0039079189300537
nick
无参装饰器
is_login_dict = {'username:None'}
def login_deco(func):
    def wrapper(*args,**kwargs):
        if not is_login_dict['username']:
            username = input('请输入你的用户名:').strip()
            if username != 'nick':
                print('非法登录')
                return
            is_login_dict['username'] = username
            res = func(*args,**kwargs)
            return res
        else:
            res = func(*args,**kwargs)
            return res
    return wrapper
@login_deco
def shopping():
    print('from shopping')
    
@login_deco
def withdraw():
    print('from withdraw')
有参装饰器
is_login_dict = {'username':None}
def auth(origin):
    def login_deco(func):
        def wrapper(*args,**kwargs):
            if origin == 'file':
                if not is_login_dict['username']:
                    username = input('请输入你的用户名:').strip()
                    if username != 'nick':
                        print('非法登录')
                        return
                    is_login_dict['username'] = username
                    res = func(*args,**kwargs)
                    return res
                else:
                    res = func('*args',**kwargs)
                    return res
            elif origin == 'mongodb':
                print('非法登录')
            else:
                print('输错了')
        return wrapper 
    return login_deco
@auth('file')
def shopping():
    print('from shopping')
    
@auth('mongodb')
def withdraw():
    print('from withdraw')

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号