28:函数闭包与装饰器

柳志军 / 2024-08-28 / 原文

l=[1,3]
l.__iter__() #迭代器
# 装饰器:本质就是函数,功能是为其他函数添加附加功能
# 原则:
# 1.不修改被修饰函数的源代码
# 2.不修改被修饰函数的调用方式
# 装饰器的知识储备
# 装饰器=高阶函数+函数嵌套+闭包
#a
def cal(l):
    res=0
    for i in l:
        res+=i
    return res
print (cal (range(100)))

  

#b
import time
def cal(l):
    start_time=time.time ()
    res=0
    for i in l:
        time.sleep(0.1)
        res+=i
    stop_time = time.time ()
    print('函数的运行时间是%s'%(stop_time-start_time))
    return res
print(cal (range(100)))

  

#c
import time

def timmer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        stop_time = time.time()
        print('函数运行时间是%.2f秒' % (stop_time - start_time))
        return res
    return wrapper

@timmer
def cal(l):
    res = 0
    for i in l:
        time.sleep(0.1)
        res += i
    return res

res = cal(range(20))
print(res)

  



# 高阶函数
# 高阶函数定义:
# 1.函数接收的参数是一个函数名
# 2.函数的返回值是一个函数名
# 3.满足上述条件任意一个,都可称之为高阶函数
# 高阶函数示范
# 1把函数当做参数传给高阶函数
def foo():
    print('你好啊诸葛孔明')

def test(func):
    print(func)
    func()

test(foo)

  

# 2把函数当做参数传给高阶函数
import time
def foo():
    time.sleep(3)
    print('你好啊诸葛孔明')

def test(func):
    print(func)
    start_time=time.time()
    func()
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))
foo()
test(foo)

# 函数返回值是函数名
def foo():
    print('from the foo')
def test(func):
    return func

res=test(foo)
print(res)
res()

foo=test(foo)
print(res)
foo()

  

#2
import time
def foo():
    time.sleep(3)
    print('来自foo')

#不修改foo源代码
#不修改foo调用方式


#多运行了一次,不合格

def timer(func):
    start_time=time.time()
    func()
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))
    return func
foo=timer(foo)
foo()

  

# 高阶函数总结
# 1.函数接收的参数是一个函数名
# 作用:在不修改函数源代码的前提下,为函数添加新功能
# 不足:会改变函数的调用方式
# 2.函数的返回值是一个函数名
# 作用:不修改函数的调用方式
# 不足:不能添加新功能

import time  # 导入time模块


def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()  # 记录开始时间
        result = func(*args, **kwargs)  # 调用原函数
        stop_time = time.time()  # 记录结束时间
        print('函数运行时间是  %s 秒' % (stop_time - start_time))
        return result  # 返回原函数的返回值

    return wrapper  # 返回新的函数


# 假设有一个函数 foo
def foo():
    time.sleep(1)  # 模拟函数执行时间


# 使用装饰器
foo = timer(foo)

# 调用被装饰的函数
foo()

  


#函数嵌套作用域
# def bar():
#     print('from bar')
#
# def foo():
#     print('from foo')
#     def test():
#         pass

def father(auth_type):
    # print('from father %s' %name)
    def son():
        # name='zhugekongming_1'
        # print('我的爸爸是%s' %name)
        def grandson():
            print('我的爷爷是%s' %auth_type)
        grandson()
    # print(locals())
    son()
# father('zhugekongming')
father('filedb')

  


#装饰器的架子
def timmer(func):
    def wrapper ():
        print(func)
        func ()
    return wrapper

#装饰器实现
import time
def timmer(func): #func=test
    def wrapper():
        # print(func)
        start_time=time.time()
        func() #就是在运行test()
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
    return wrapper

@timmer #test=timmer(test)
def test():
    time.sleep(3)
    print('test函数运行完毕')
test()

# res=timmer(test)  #返回的是wrapper的地址
# res()  #执行的是wrapper()

# test=timmer(test)  #返回的是wrapper的地址
# test()  #执行的是wrapper()

#  @timmer  就相当于 test=timmer(test)

  



#加上返回值
import time
def timmer(func): #func=test
    def wrapper():
        start_time=time.time()
        res=func() #就是在运行test()
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
        return res
    return wrapper

@timmer #test=timmer(test)
def test():
    time.sleep(3)
    print('test函数运行完毕')
    return '这是test的返回值'

res=test()  #就是在运行wrapper
print(res)

  



#加上参数
import time
def timmer(func): #func=test1
    def wrapper(*args,**kwargs): #test('linhaifeng',age=18)  args=('linhaifeng')  kwargs={'age':18}
        start_time=time.time()
        res=func(*args,**kwargs) #就是在运行test()         func(*('linhaifeng'),**{'age':18})
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
        return res
    return wrapper

# @timmer #test=timmer(test)
def test(name,age):
    time.sleep(3)
    print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
    return '这是test的返回值'

@timmer
def test1(name,age,gender):
    time.sleep(1)
    print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender))
    return '这是test的返回值'

# res=test('zhugekongming',age=18)  #就是在运行wrapper
# # print(res)
# test1('alex',18,'male')

test1('alex',18,'male')


# def test2(name,age,gender): #test2(*('alex',18,'male','x','y'),**{})
#     #name,age,gender=('alex',18,'male','x','y')
#     print(name)
#     print(age)
#     print(gender)
#
# def test1(*args,**kwargs):
#     test2(*args,**kwargs)  #args=('alex',18,'male','x','y') kwargs={}
#
# # test2('alex',18,gender='male')
#
# test1('alex',18,'male')

  

#验证功能装饰器:
user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'zhugeliang','passwd':'123'},
    {'name':'zhaoyun','passwd':'123'},
    {'name':'guanyu','passwd':'123'},
]
current_dic={'username':None,'login':False}


def auth_func(func):
    def wrapper(*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['name'] and passwd == user_dic['passwd']:
                current_dic['username']=username
                current_dic['login']=True
                res = func(*args, **kwargs)
                return res
        else:
            print('用户名或者密码错误')

    return wrapper

@auth_func
def index():
    print('欢迎来到京东主页')

@auth_func
def home(name):
    print('欢迎回家%s' %name)

@auth_func
def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

print('before-->',current_dic)
index()
print('after--->',current_dic)
home('产品经理')
# shopping_car('产品经理')