day12-闭包函数、装饰器

闭包函数

之前我们都是通过参数将外部的值传给函数,而闭包打破了层级关系,把局部变量拿到全局使用,并把外部的变量封装到内部函数中,然后下次直接调用就行了。

举个例子:

# 闭包函数
def outter():
    x = 1
    def inner():
        print(x)
    return inner

f = outter()		# 返回  f = inner
f()					# 直接调用局部变量inner()

在这个闭包函数中f = outter(1)在调用函数outter时,f返回的结果时inner,这是一个在函数内部定义的一个函数名,执行f()时就是在执行inner()函数,它实现了将局部变量拿到全局使用,打破了层级关系

返回的对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

import requests
def outter(url):
    def spider():
        responser = requests.get(url)
        print(responser.text)
    return spider
baidu = outter("https://www.baidu.com")
baidu()
taobao = outter("https://www.taobao.com")
taobao()

装饰器

装饰器就是用来装饰的工具,本质上其实是一个函数,只不过这个函数具有装饰的功能,改变功能的时候不改变被装饰对象的调用方式,并且不改变被装饰对象的源代码

无参装饰器

is_login_dict = {'username': None}


def login_deco(func):
    
    def wrapper(*args, **kwargs): 

        if not is_login_dict['username']:

            username = input('请输入你的用户名》》》').strip()

            if username != 'fanping':
                print('非法登录')

                return

            is_login_dict['username'] = username

            res = func(*args, **kwargs)  

            return res
        else:
            res = func(*args, **kwargs)  

            return res         

    return wrapper


@login_deco                # @login_deco 在此相当于是做了 shopping = login_deco(shopping)的操作
def shopping():
    print('from shopping')


@login_deco                 # @login_deco 在此相当于是做了 withdraw = login_deco(withdraw)的操作
def withdraw():
    print('from withdraw')

有参装饰器

is_login_dict = {'username': None}

def auth(origin):
    
    def login_deco(func):

        def wrapper(*args, **kwargs):  # 赋值后的time_sleep

            if origin == 'file':

                if not is_login_dict['username']:

                    username = input('请输入你的用户名》》》').strip()

                    if username != 'fanping':
                        print('非法登录')

                        return

                    is_login_dict['username'] = username

                    res = func(*args, **kwargs)  # 真正的time_sleep

                    return res
                else:
                    res = func(*args, **kwargs)  # 真正的time_sleep

                    return res

            elif origin == 'mongodb':
                print('非法登录')
                
            else:
                print('dsb')


        return wrapper
    
    return login_deco

# @auto('file')相当于是做了以下操作
# f = origin('file')  # login_deco
# shopping = f(shopping)


@auth('file')
def shopping():
    print('from shopping')


@auth('mongodb')
def withdraw():
    print('from withdraw')

装饰器模板

def deco(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

@deco
def func():
    pass

posted @ 2019-05-31 20:45  Never&say&die  阅读(139)  评论(0编辑  收藏  举报