努力学习技术的小白 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条)

报告相同问题?

悬赏问题

  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机