闭包函数、装饰器

一、 闭包函数

#闭:指的是定义在函数内部的函数
#!!!作用域关系 在函数定义阶段就规定死了,与调用位置无关
def outter():
    x=2
    def inner():
        x=1
        print('from inner',x)
    return inner

f=outter() #f=inner
print(f)
f()

'''
<function outter.<locals>.inner at 0x0357AA50>
from inner 1
'''

# 闭包函数:
# 1、定义在函数内部的函数
# 2、 并且该函数包含对外部函数作用域中名字的引用,该函数就称为闭包函数
def outter():
    name='egon'
    def inner():
        print('my name is %s' %name)
    return inner
f=outter()
f()
'''
my name is egon
'''

二、装饰器

海燕

1、开放封闭原则

软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的
也就是说我们必须找到一种解决方案:
    能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能
    总结,
    原则如下:
        1、不修改源代码
        2、不修改调用方式
    目的:
        在遵循1和2原则的基础上扩展新功能

2、什么是装饰器?

器指的工具,装饰指的是为被装饰对象添加新功能
完整含义:
    装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰对象添加新功能
    装饰器与被装饰的对象均可以是任意可调用的对象
装饰器的本质:闭包函数

装饰器模板:

#装饰器模板
def wrapper(func):
    def inner(*args,**kwargs):
        '''函数执行之前的内容扩展'''
        res=func(*args,**kwargs)
        '''函数执行之前的内容扩展'''
        return res
    return inner

(1)无参装饰器

认证装饰器实现

import time
current_user={
    'username':None,
    # 'login_time':None
}

def auth(func):
    # func=index
    def wrapper(*args,**kwargs):
        if current_user['username']:
            print('已经登陆过了')
            res=func(*args,**kwargs)
            return res

        uname=input('用户名>>: ').strip()
        pwd=input('密码>>: ').strip()
        if uname == 'egon' and pwd == '123':
            print('登陆成功')
            current_user['username']=uname
            res=func(*args,**kwargs)
            return res
        else:
            print('用户名或密码错误')
    return wrapper

@auth #index=auth(index)
def index():
    time.sleep(1)
    print('welcome to index page')
    return 122

@auth
def home(name):
    time.sleep(2)
    print('welcome %s to home page' %name)

index()
home('egon')

'''
用户名>>: egon
密码>>: 123
登陆成功
welcome to index page
已经登陆过了
welcome egon to home page
'''
import time
current_user={
    'username':None,
    # 'login_time':None
}

def auth(func):
    # func=index
    def wrapper(*args,**kwargs):
        if current_user['username']:
            print('已经登陆过了')
            res=func(*args,**kwargs)
            return res

        uname=input('用户名>>: ').strip()
        pwd=input('密码>>: ').strip()
        if uname == 'egon' and pwd == '123':
            print('登陆成功')
            current_user['username']=uname
            res=func(*args,**kwargs)
            return res
        else:
            print('用户名或密码错误')
    return wrapper

def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(stop_time-start_time)
        return res
    return wrapper

@timmer # timmer 统计的是auth+index的执行时间
@auth
def index():
    time.sleep(1)
    print('welcome to index page')
    return 122

index()

'''
用户名>>: egon
密码>>: 123
登陆成功
welcome to index page
8.211769342422485
'''
叠加多个装饰器

(2)有参装饰器

import time
current_user={
    'username':None,
    # 'login_time':None
}

def auth(engine):
    # engine='file'
    def auth2(func):
        # func=index
        def wrapper(*args,**kwargs):
            if engine == 'file':
                if current_user['username']:
                    print('已经登陆过了')
                    res=func(*args,**kwargs)
                    return res

                uname=input('用户名>>: ').strip()
                pwd=input('密码>>: ').strip()
                if uname == 'egon' and pwd == '123':
                    print('登陆成功')
                    current_user['username']=uname
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('用户名或密码错误')
            elif engine == 'mysql':
                print('基于MyQL的认证')
            elif engine == 'ldap':
                print('基于LDAP的认证')
        return wrapper
    return auth2

@auth('file') #@auth2 #index=auth2(index) #index=wrapper
def index():
    time.sleep(1)
    print('welcome to index page')
    return 122
index() # wrapper()

'''
用户名>>: egon
密码>>: 123
登陆成功
welcome to index page
'''

'''
@auth('ldap') 
def index():
    time.sleep(1)
    print('welcome to index page')
    return 122

index() 

#打印结果 : 基于LDAP的认证
'''
原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13306604.html