阅读目录

一 什么是装饰器

二 装饰器需要遵循的原则

三 实现装饰器知识储备

四 高阶函数

五 函数嵌套

六 闭包

七 无参装饰器

八 装饰器应用示例

 

一 什么是装饰器


器即函数


装饰即修饰,意指为其他函数添加新功能


装饰器定义:本质就是函数,功能是为其他函数添加新功能


 

二 装饰器需要遵循的原则


1.不修改被装饰函数的源代码(开放封闭原则)


2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式


 

三 实现装饰器知识储备


装饰器=高阶函数+函数嵌套+闭包


 

四 高阶函数


高阶函数定义:

1.函数接收的参数是一个函数名


2.函数的返回值是一个函数名


3.满足上述条件任意一个,都可称之为高阶函数



 def foo():

    print('我的函数名作为参数传给高阶函数')

def gao_jie1(func):

    print('我就是高阶函数1,我接收的参数名是%s' %func)

    func()


def gao_jie2(func):

    print('我就是高阶函数2,我的返回值是%s' %func)

    return func


gao_jie1(foo)

gao_jie2(foo)

 

 #高阶函数应用1:把函数当做参数传给高阶函数

import time

def foo():

    print('from the foo')


def timmer(func):

    start_time=time.time()

    func()

    stop_time=time.time()

    print('函数%s 运行时间是%s' %(func,stop_time-start_time))

timmer(foo)

#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式

 

 #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名

import time

def foo():

    print('from the foo')


def timmer(func):

    start_time=time.time()

    return func

    stop_time=time.time()

    print('函数%s 运行时间是%s' %(func,stop_time-start_time))

foo=timmer(foo)

foo()

#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能

 高阶函数总结

1.函数接收的参数是一个函数名

  作用:在不修改函数源代码的前提下,为函数添加新功能,

  不足:会改变函数的调用方式

2.函数的返回值是一个函数名

  作用:不修改函数的调用方式

  不足:不能添加新功能


 

五 函数嵌套


  1 def father(name):

 2     print('from father %s' %name)

 3     def son():

 4         print('from son')

 5         def grandson():

 6             print('from grandson')

 7         grandson()

 8     son()

 9 

10 father('tom')

  

六 闭包


  1 '''

 2 闭包:在一个作用域里放入定义变量,相当于打了一个包

 3 '''

 4 def father(name):

 5     def son():

 6         # name='jack'

 7         print('is [%s]' %name)

 8         def grandson():

 9             # name='wupeiqi'

10             print('is [%s]' %name)

11         grandson()

12     son()

13 

14 father('jack')

  

七 无参装饰器


无参装饰器=高级函数+函数嵌套


基本框架


1 #这就是一个实现一个装饰器最基本的架子

2 def timer(func):

3     def wrapper():

4         func()

5     return wrapper

加上参数


1 def timer(func):

2     def wrapper(*args,**kwargs):

3         func(*args,**kwargs)

4     return wrapper

加上功能


 1 import time

2 def timer(func):

3     def wrapper(*args,**kwargs):

4         start_time=time.time()

5         func(*args,**kwargs)

6         stop_time=time.time()

7         print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))

8     return wrapper

 加上返回值


 1 import time

2 def timer(func):

3     def wrapper(*args,**kwargs):

4         start_time=time.time()

5         res=func(*args,**kwargs)

6         stop_time=time.time()

7         print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))

8         return res

9     return wrapper

 使用装饰器


 1 def cal(array):

2     res=0

3     for i in array:

4         res+=i

5     return res

7 cal=timer(cal)

8 cal(range(10))

 语法糖@


 1 @timer  #@timer就等同于cal=timer(cal)

2 def cal(array):

3     res=0

4     for i in array:

5         res+=i

6     return res

8 cal(range(10))

  

八 装饰器应用示例



 user_list=[

    {'name':'alex','passwd':'123'},

    {'name':'linhaifeng','passwd':'123'},

    {'name':'wupeiqi','passwd':'123'},

    {'name':'yuanhao','passwd':'123'},

]


current_user={'username':None,'login':False}


def auth_deco(func):

    def wrapper(*args,**kwargs):

        if current_user['username'] and current_user['login']:

            res=func(*args,**kwargs)

            return res

        username=input('用户名: ').strip()

        passwd=input('密码: ').strip()


        for index,user_dic in enumerate(user_list):

            if username == user_dic['name'] and passwd == user_dic['passwd']:

                current_user['username']=username


                current_user['login']=True

                res=func(*args,**kwargs)

                return res

                break

        else:

            print('用户名或者密码错误,重新登录')


    return wrapper


@auth_deco

def index():

    print('欢迎来到主页面')


@auth_deco

def home():

    print('这里是你家')


def shopping_car():

    print('查看购物车啊亲')


def order():

    print('查看订单啊亲')


print(user_list)

# index()

print(user_list)

home()

 

 user_list=[

    {'name':'tom','passwd':'123'},

    {'name':'jack','passwd':'123'},

  ]


current_user={'username':None,'login':False}

def auth(auth_type='file'):

    def auth_deco(func):

        def wrapper(*args,**kwargs):

            if auth_type == 'file':

                if current_user['username'] and current_user['login']:

                    res=func(*args,**kwargs)

                    return res

                username=input('用户名: ').strip()

                passwd=input('密码: ').strip()


                for index,user_dic in enumerate(user_list):

                    if username == user_dic['name'] and passwd == user_dic['passwd']:

                        current_user['username']=username

                        current_user['login']=True

                        res=func(*args,**kwargs)

                        return res

                        break

                else:

                    print('用户名或者密码错误,重新登录')

            elif auth_type == 'ldap':

                print('auth')

                res=func(*args,**kwargs)

                return res

        return wrapper

    return auth_deco



#auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')

#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数

@auth(auth_type='ldap')

def index():

    print('欢迎来到主页面')


@auth(auth_type='ldap')

def home():

    print('home')


def shopping_car():

    print('shopping')


def order():

    print('check order')


# print(user_list)

index()

# print(user_list)

home()