努力学习技术的小白 2021-05-23 01:23 采纳率: 100%
浏览 24
已采纳

关于装饰器的问题,请大佬帮忙回答下

各位大佬

       近期在学习python的装饰器的时候,碰到个如下问题,想了解下应该通过什么样的方法避免这种问题发生,具体场景如下:

       背景1:主函数时用来计算从0 到输入值的和,使用的是函数迭代的方法。

       背景2:装饰器是两个辅助函数,一个是用来统计代码执行时间,一个是用来打印日志

       有两个问题:

       问题1:装饰器加强过主函数后,在迭代过程中会重复执行辅助函数,导致打印多次,如果只打印一次有办法吗?

       问题2:打印日志的时候,打印内容中的执行方法只能是count_time()方法返回的结果,有办法打印到真正的主函数的名字吗?(除了调换两个装饰器的前后顺序)

def count_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print('程序执行耗时%.4f' % (end_time - start_time))
        return result

    return wrapper


def log_record(func):
    def wrapper1(*args, **kwargs):
        result = func(*args, **kwargs)
        print('【' + threading.currentThread().name + '】执行的方法是:【' + func.__name__ + '】')
        return result

    return wrapper1


# 第三部分:将内容求和/统计执行时间/打印日志简化,使用装饰器的形式来简化
@log_record
@count_time
def sum_num(num):
    if num == 1:
        time.sleep(1)
        return 1
    return num + sum_num(num - 1)


sum_num(3)
# 所以结果打印三次,是因为用到了迭代,装饰器使用一次后就永久生效,迭代时再次调用这个方法,仍旧会执行装饰器的辅助函数
  • 写回答

2条回答 默认 最新

  • CSDN专家-HGJ 2021-05-23 02:32
    关注

    为解决重复打印问题,可将主函数改写成嵌套函数,这样不管内部迭代函数迭代多少次,因为只调用主函数comp一次,这时装饰器的辅助函数也只执行一次,代码的最后可改写成这样:

    @log_record
    @count_time
    def comp(num):
        def sum_num(num):
            if num == 1:
                time.sleep(1)
                return 1
            return num + sum_num(num - 1)
        return sum_num(num)
    
    print(comp(10))
    
    #运行结果
    程序执行耗时1.0052
    【MainThread】执行的方法是:【wrapper】
    55
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 射频功率问题,解答者有酬谢!
  • ¥80 构建降雨和积水的预测模型
  • ¥15 #Qt Transform setTransform()在鼠标拖动移动视角是一致在原地不动,无法变换视角(细微观察似乎视图有在原地抖动),无法变换视角(细微观察似乎视图有在原地抖动)
  • ¥50 如何利用无人机拍摄的数码照片测量鸟卵的长短径
  • ¥100 github贡献者给与奖励
  • ¥15 使用DS18B20+ESP8266获取温度数据返回-127.00
  • ¥15 odbc代码新增sqlserver数据源
  • ¥15 求一个USB指纹识别的驱动
  • ¥15 wps中工作表与工作表之间怎么汇总信息?
  • ¥50 请教Windows server 2012 R2的DCOM配置问题