闭包函数和装饰器

闭包函数

打破层级关系,把局部变量拿到全局使用

使用参数的形式:

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()

给你网址:https://www.baidu.com

装饰器

装饰器本质上其实也是一个函数,只不过该函数的功能是用来为其他函数添加额外的功能,并且改变功能的时候不改变原来的调用方式,并且不改变原来函数的代码。

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')
posted @ 2019-05-31 21:11  小小罗code  阅读(140)  评论(0编辑  收藏  举报