day01 (python进阶----装饰器)

装饰器———就是名称空间与作用域和闭包函数的综合运用。

名称空间分为:内置名称空间,示例:  print、input等这些内置函数属于内置名称

                          全局名称空间,示例:  x=1,变量名在函数定义中或函数外的就是全局名称。

                          局部名称空间,示例: f=666,在函数定义里面的,嵌套在函数内的事局部名称

名称查找顺序是由局部==》全局==》内置

闭包函数:就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包.
1、装饰器定义:修饰别人的工具,修饰添加功能,工具指的是函数,装饰器可以运用于各种函数对象。简单的来说就是一个人经过某个空间(函数)穿了一件新衣服,变帅了。本质还是一个普通的人,只是被装饰了

2、装饰器分为:无参装饰器(常用)和有参装饰器,本质区别就是无参装饰器只有两层函数嵌套,而有参装饰器有三层或者是多个变量名需要定义。

基于以上对名称空间和闭包函数以及装饰器概念的了解,接下来做一个示例来分析:

一般的简单函数:

def func():
    f=666
func()

当我有需求需要在给一个函数里面的体代码(f=666),添加一个新功能且不更改源代码和原本的调用方式,这时就需要用带装饰器,如我需要给其添加一个验证功能如示例:

def func():
    name=input('请输入你的账号====>')
    pwd=input('请输入你的密码====>')
    if name == 'yeqing' and pwd =='123':
        print('登录成功,开始装饰')
        f=666
        return f
    else:
        print('账号密码错误')
func()
#因为需要让f=666 不固定死,由此将f=666,改为f=ff(*args,**kwargs),又因为需要得要ff的赋值,所以用到了闭包.
#最终需要返回原来的值,所以用到return。
def out(ff):
    def func(*args,**kwargs):
        name=input('请输入你的账号====>')
        pwd=input('请输入你的密码====>')
        if name == 'yeqing' and pwd =='123':
            print('登录成功,开始装饰')
            f=ff(*args,**kwargs)
            return f
        else:
            print('账号密码错误')
    return func
#此时我需要装饰一下(x,y),验证成功后开始装饰,装饰成功后打印牛逼
def index(x,y):
    print('牛逼的 %s %s' %(x,y))


def out(ff):          #全局名称的作用域
    def func(*args,**kwargs):
        name=input('请输入你的账号====>')       #内置名称的作用域
        pwd=input('请输入你的密码====>')
        if name == 'yeqing' and pwd =='123':
            print('登录成功,开始装饰')
            f=ff(*args,**kwargs)          #局部名称的作用域
            return f
        else:
            print('账号密码错误')
    return func

index=out(index)
res=index(1,2)
print(res)
#由此得到得到一个装饰后的牛逼,既没有更改原来定义的(x,y),也没改调用方式,从而得到装饰后的牛逼的1和2

这就是无参装饰器。

有参装饰器:和无参装饰器原理一样,但是在某些特定的场景我们函数体内需要定义多种值,这是因为函数体内条件增加了,需要多一个或多个变量值进行传参。由此需要有参装饰器,如函数体内新增了db_type的条件判断示例:

def index(x,y):
    print('牛逼的 %s %s' %(x,y))
def out(ff,dbtype):          #全局名称的作用域
    def func(*args,**kwargs):
        if dbtype =='file':
            print('基于文件格式')
            name=input('请输入你的账号====>')       #内置名称的作用域
            pwd=input('请输入你的密码====>')
            if name == 'yeqing' and pwd =='123':
                print('登录成功,开始装饰')
                f=ff(*args,**kwargs)          #局部名称的作用域
                return f
            else:
                print('账号密码错误')
        else:
           print('格式不对')
    return func

index=out(index,'file')
index(1,2)
#由此得到一个基于文件格式打开的一个装饰后的牛逼,既没有更改原来定义的(x,y),也没改调用方式,从而得到装饰后的牛逼的1和2

明天将对装饰器进行优化和简单化,将引用语法糖,重新改造上面的示例

你可能感兴趣的:(python学习,python,开发语言,后端)