day9.高阶函数,装饰器(一个参数,多个参数),装饰器实现一个计时器,实现添加日志(8.22)

# map(fun, range(1,11))

# 主要理解执行的过程及分析----高阶函数,返回值是一个函数(定义函数并不会执行函数内容, 调用时才会执行.)
def compare1(base):  # base=10
    def compare2(y):  # y=3
        return base > y   # 10>3 True
    return compare2  # compare2===函数名

compare_base_10 = compare1(10)
print(compare_base_10)  # 函数名
res = compare_base_10(3)
print(res)

print(abs)
def add(x,y):
    return x+y
print(add)

*****装饰器***
# 产品经理和程序员

# ATM

# 用户使用ATM的时候, 执行程序之前祝福语==“国庆节快乐”,
#                   执行程序之后打个广告===="欢迎再次光临西部开源.....".



# 1. 解决问题: 在函数执行之前和执行之后添加功能, 调用函数的方式改变了.
# 2. 不改变原有函数的调用方法: 函数里面潜逃函数, 并且返回嵌套的函数login = desc(login)

def desc(fun):  # fun = login   #1).  需要传递一个函数, 要装饰的函数
    def add_info():             # 2). 装饰器函数里面嵌套函数
        print("五一快乐")
        fun()  # login()
        print("欢迎再次光临西部开源.....")
    return add_info             #3). 返回值是嵌套的函数对象

# 语法糖
@desc   # login = desc(login)    # 4). 如何调用装饰器(两种方式)
def login():
    # print("国庆节快乐")
    print("login......")
    # print("欢迎再次光临西部开源.....")
# login = desc(login)  # 返回值是一个函数
# login()

login()


def logout():
    print("logout......")

logout = desc(logout)
logout()

def saveMoney():
    print("存钱........")



def transferMoney():
    print("转账.........")



# 几百个函数, 此处省略......

# add_info(login)

03 装饰器实现一个计时器
# 装饰器需求: 获取每个函数的执行时间
#       1).函数执行之前计算时间;
#       2).函数执行之后计算时间


#  实验1:看字符串拼接的效率
#           1). “hello” + "world"
#           2). " ".join(['hello', “world”])


# 实验2: 检测列表生成式和map的效率高低, n为函数传入的参数===两者实力相当
#       1). [n*2 for i in range(n)]
#       2). map(lambda x:x*2, range(n))



import random
import string
import time
li = [ random.choice(string.ascii_letters) for i in range(100)]

def timeit(fun): # fun_list
    def wrapper(*args, **kwargs):   # 接收可变参数和关键字参数
        # args: 元组   kwargs: 字典  args=(5,)
        # 函数执行之前
        start_time = time.time()
        # 执行函数
        fun(*args, **kwargs)  # args解包, 5,|  对于元组解包, 对于字典解包
        # 执行函数之后
        end_time = time.time()
        print("运行时间为:%.6f" % (end_time - start_time))
    return  wrapper


@timeit
def con_add():
    s = ''
    for i in li:
        s += (i+",")
    print(s)


@timeit
def join_add():
    print(",".join(li))


@timeit   #  fun_list=timeit(fun_list)   # fun_list = wrapper
def fun_list(n):
    print([2*i for i in range(n)])

@timeit
def fun_map(n):
    print(list(map(lambda x:x*2, range(n))))

con_add()
join_add()
fun_list(500000)   #
fun_map(500000)
****04装饰器之函数的属性变化解决方案


import random
import string
import time
import functools
# 高阶函数的一些方法
from functools import reduce

# 问题1: 装饰的函数有返回值的解决方法:
# 问题2:如何保留被装饰函数的函数名和帮助文档信息. @functools.wraps(fun)
def timeit(fun): # fun_list
    """这是一个装饰器timeit"""
    @functools.wraps(fun)
    # 可以保留被装饰函数的函数名和帮助文档信息.
    def wrapper(*args, **kwargs):   # 接收可变参数和关键字参数  # 100
        """这是一个wrpper函数"""
        # args: 元组   kwargs: 字典  args=(100,)
        # 函数执行之前
        start_time = time.time()
        # 执行函数
        res = fun(*args, **kwargs)  # args解包, 100,|  对于元组解包, 对于字典解包
        # fun_list(100)
        # 执行函数之后
        end_time = time.time()
        print("运行时间为:%.6f" % (end_time - start_time))
        return res
    return  wrapper

@timeit         # fun_list=timeit(fun_list)  # fun_list = wrapper
def fun_list(n):
    """这是fun_list函数, 被timeit装饰"""
    return [2*i for i in range(n)]

@timeit
def fun_map(n):
    """这是fun_map函数"""
    return   map(lambda x:x*2, range(n))

@timeit
def fun():
    print("hello")

# print(fun_list(100))   # wrapper(100)
# print(fun_map(100))
# fun()


print(fun_list.__name__)
print(fun_list.__doc__)
***练习添加日志***
# 1. 创建add_log装饰器, 被装饰的函数打印日志信息;
# 2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx


import functools
import time

# format
def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        # run_time = time.ctime()
        # fun_name = fun.__name__
        start_time = time.time()
        res = fun(*args, **kwargs)
        end_time = time.time()
        print("[%s] 函数名: %s, 运行时间:%.5f, 运行返回值结果:%d"
              %(time.ctime(), fun.__name__, end_time-start_time, res )
              )
        return res
    return wrapper

@add_log
def add(x,y):
    time.sleep(0.1)
    return x+y

print(add(1,2))
***07判度变量的数据类型***
# 1. 创建add_log装饰器, 被装饰的函数打印日志信息;
# 2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx


import functools
import time

# format
def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        # run_time = time.ctime()
        # fun_name = fun.__name__
        start_time = time.time()
        res = fun(*args, **kwargs)
        end_time = time.time()
        print("[%s] 函数名: %s, 运行时间:%.5f, 运行返回值结果:%d"
              %(time.ctime(), fun.__name__, end_time-start_time, res )
              )
        return res
    return wrapper

@add_log
def add(x,y):
    time.sleep(0.1)
    return x+y

print(add(1,2))

***08带有多个装饰器的函数***
# @is_login, @is_admin


#
# # 需求: 用户登陆验证的装饰器is_login
# #       1). 如果用户登陆成功, 则执行被装饰的函数;
# #       2). 如果用户登陆不成功, 则执行登陆函数
#
#
# # 需求: 判断登陆用户是否未管理员is_admin(此处管理员只有一个为:admin用户)
# #      1).如果用户为管理员, 则执行被装饰的函数;
# #      2).如果用户不是管理员, 则报错;
# import functools
# login_users = ['admin', 'root']
#
#
#
# def is_admin(fun):
#     @functools.wraps(fun)
#     def wrapper(*args, **kwargs):
#         #
#         if kwargs.get("name") == 'admin':
#             res = fun(*args, **kwargs)
#             return  res
#         else:
#             return "Error: 您没有权限访问该网站"
#     return wrapper
#
# def is_login(fun):  # fun: writeBlog
#     @functools.wraps(fun)
#     def wrapper(*args, **kwargs):   # name="admin"  # kwargs={"name":"admin"}
#         # 判断写博客的这个用户是否登陆成功;
#         if kwargs.get("name") in login_users:
#             res = fun(*args, **kwargs)
#             return res
#         else:
#             res=login()
#         return res
#     return wrapper
#
# # 必须登陆成功
# @is_login    # writeBlog = is_login(writeBlog)
# @is_admin     # 先判断是否为admin用户
# def writeBlog(name):
#     return "编写博客"
#
# def login():
#     return "登陆。。。。"
#
# # 是否登陆成功都可以执行代码
# def news():
#     print("新闻......")
#
# print(writeBlog(name="root"))




def makebold(fun):
    print("bold1")
    def wrapper1(*args, **kwargs):
        print("bold2")
        return  fun(*args, **kwargs)  # wrapper
    return  wrapper1

def makei(fun):   # fun=login
    print("i1")
    def wrapper(*args, **kwargs):
        print("i2")
        return  fun(*args, **kwargs)
    return  wrapper

#  当有多个装饰器时, 从下到上调用装饰器,
#  真实wrapper内容执行是从上到下执行.
@makebold  # login = makebold(login)   # login为wrapper1
@makei    # login = makei(login)    # login为wrapper
def login():
    return "登陆"
print(login())
***09**8带有参数的装饰器***
# 创建装饰器, 要求如下:
# 1. 创建add_log装饰器, 被装饰的函数打印日志信息;
# 2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx


import functools
import time

# format
def log(kind):  # kind="debug"
    def add_log(fun):
        @functools.wraps(fun)
        def wrapper(*args, **kwargs):
            # run_time = time.ctime()
            # fun_name = fun.__name__
            start_time = time.time()
            res = fun(*args, **kwargs)
            end_time = time.time()
            print("<%s> [%s] 函数名: %s, 运行时间:%.5f, 运行返回值结果:%d"
                  %(kind, time.ctime(), fun.__name__, end_time-start_time, res )
                  )
            return res
        return wrapper
    return  add_log
@log("debug")
#  log("debug")==> 返回值是add_log
#  add=add_log(add)
def add(x,y):
    time.sleep(0.1)
    return x+y
print(add(1,2))
# wrapper(1,2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值