python基础09--函数闭包与装饰器

装饰器:

本质:就是一个函数

功能:为其他函数添加附加功能

原则:1.不修改被修饰函数的源代码

           2.不修改被修饰函数的调用方式

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

 

高阶函数:结合两种高阶函数的方式,不能满足装饰器的功能,多执行了一次操作

import time
def foo():
    print("来自foo")
def test(func):
    print("来自test")
    start_time=time.time()
    func()
    end_time=time.time()
    print("运行时间%s" %(start_time-end_time))
    return func
foo=test(foo)  
foo()
View Code

 

装饰器的基本实现

import time
def foo(func):   #func=test
    def too():
        start_time=time.time()
        func()
        end_time=time.time()
        print("运行时间%s" %(start_time-end_time))
    return too

@foo
def test():
    time.sleep(3)
    print("函数运行完毕")
# test=foo(test)       #修改了一部分源代码,可在函数前加上@foo(完成了test=foo(test)的操作),表示调用装饰器内容
# test()
test()
View Code

 

ps:1.返回值的问题,保存test函数中的返回值,装饰器中需要有变量接收返回的值

import time
def foo(func):   #func=test
    def too():
        start_time=time.time()
        res=func()    #***接收test的返回值
        end_time=time.time()
        print("运行时间%s" %(start_time-end_time))
        return res   #***最终返回res的值
        
    return too

@foo
def test():
    time.sleep(3)
    print("函数运行完毕")
    return "test的返回值"
# test=foo(test)    #返回的是too的地址
#  test()          #执行too
# #修改了一部分源代码,可在函数前加上@foo(完成了test=foo(test)的操作),表示调用装饰器内容

res=test()
print(res)
View Code

       2. 加入参数,利用可变长参数接收各种类型的数据

import time
def foo(func):   #func=test
    def too(*args,**kwargs):  #保证参数原封不动原给下一个func
        start_time=time.time()
        res=func(*args,**kwargs)
        end_time=time.time()
        print("运行时间%s" %(start_time-end_time))
        return res

    return too

@foo
def test(name,age,gender):    #(name,age,gender)=("alex",12,"male) 通过解压序列,获得一一对应的关系传入
    time.sleep(3)              
    print("函数运行完毕","我是%s,年龄为%s,性别是%s" %(name,age,gender))
    return "test的返回值"

res=test("alex",12,"male")
print(res)
View Code

 

ps:解压序列:

取开头和结尾的值:

l=(1,23,4354,76,8,)
a,*_,c=l         #*_表示中间的全部数
print(a,c)
View Code

位置调换:

a1=1
a2=2
a1,a2=a2,a1
print(a1,a2)
View Code

 

加上验证功能例子:

user_list=[{"username":"alex","passwd":"123"},{"username":"sb","passwd":"abc"},{"username":"baby","passwd":"456"}]
current_dic={"username":None,"login":False}
def fangfa(func):
    def foo(*args,**kwargs):
        if current_dic["username"] and current_dic["login"]:
            res=func(*args,**kwargs)
            return res

        username=input("用户名:").strip()
        passwd=input("密码:").strip()
        for user_dic in user_list:
            if username== user_dic["username"] and passwd== user_dic["passwd"]:
                current_dic["username"]=username
                current_dic["login"]=True
                res=func(*args,**kwargs)
                return res
        else:
            print("用户名或密码错误")
    return foo

@fangfa
def zhuye(*args,**kwargs):
    print("欢迎来到京东主页")

@fangfa
def home(name):
    print("%s欢迎回来" %name)

@fangfa
def shopping_car(name,m1,m2,m3):
    print("%s的购物车有[%s],[%s],[%s]" %(name,m1,m2,m3))

zhuye()
home("sb")
shopping_car("sb","奶茶","可乐","巧克力")
View Code

 

闭包(加上验证类型):最终版本

user_list=[{"username":"alex","passwd":"123"},{"username":"sb","passwd":"abc"},{"username":"baby","passwd":"456"}]
current_dic={"username":None,"login":False}
def total(user_type):       ##闭包,函数最终运行的还是foo
    def fangfa(func):
        def foo(*args,**kwargs):
            if user_type == "ldap":
                print("认证类型%s" %user_type)

                if current_dic["username"] and current_dic["login"]:
                    res=func(*args,**kwargs)
                    return res

                username=input("用户名:").strip()
                passwd=input("密码:").strip()
                for user_dic in user_list:
                    if username== user_dic["username"] and passwd== user_dic["passwd"]:
                        current_dic["username"]=username
                        current_dic["login"]=True
                        res=func(*args,**kwargs)
                        return res

                else:
                    print("用户名或密码错误")
                    return
            elif user_list == "aaa":
                print("验证类型%s" %user_type)
                res=func(*args,**kwargs)
                return res
            else:
                print("用户验证类型%s错误" %user_type)
                res=func(*args,**kwargs)
                return res


        return foo
    return fangfa
@total(user_type="ldap")
def zhuye(*args,**kwargs):
    print("欢迎来到京东主页")

@total(user_type="aaa")
def home(name):
    print("%s欢迎回来" %name)

@total(user_type="dasjdk")
def shopping_car(name,m1,m2,m3):
    print("%s的购物车有[%s],[%s],[%s]" %(name,m1,m2,m3))

zhuye()
home("sb")
shopping_car("sb","奶茶","可乐","巧克力")
View Code

 

posted @ 2020-04-28 15:29  sakura*gyt  阅读(135)  评论(0编辑  收藏  举报