【问题标题】:How to make an optional decorator in Python如何在 Python 中制作可选的装饰器
【发布时间】:2016-01-28 18:37:19
【问题描述】:

我有一组 python 脚本,我想用 kernprof https://github.com/rkern/line_profiler 进行分析,但我也希望能够在没有 kernprof 的情况下在正常执行期间运行它。

在没有kernprof 的情况下,在执行期间忽略未定义的@profile 的优雅方法是什么?或任何其他装饰器。

示例代码:

    @profile
    def hello():
        print('Testing')

    hello()

运行:

    kernprof -l test.py

在@profile 方法上正确执行分析器

运行:

    python test.py 

返回错误:

    Traceback (most recent call last):
    File "test.py", line 1, in <module>
    @profile
    NameError: name 'profile' is not defined

希望避免在任何地方捕获此错误,因为我希望代码在不使用 kernprof 调用时就好像 @profile 是无操作一样执行。

谢谢! -劳拉

编辑:我最终将 cProfile 与 kcachegrind 一起使用,并完全避免使用装饰器。

Using cProfile results with KCacheGrind

python -m cProfile -o profile_data.pyprof run_cli.py

pyprof2calltree -i profile_data.pyprof && qcachegrind profile_data.pyprof.log

【问题讨论】:

    标签: python profiling python-decorators


    【解决方案1】:

    如果不从kernprof 执行,则定义一个no-op 装饰器:

    if 'profile' not in globals():
        def profile(func):
            return func
    

    【讨论】:

      【解决方案2】:

      Daniel 提出的方法的一种变体是使用以下单行代码,然后根据您是否需要进行分析:

      # Optional no-op decorator, comment when you want to profile
      def profile(func): return func
      

      【讨论】:

      • 这似乎是同一个答案。我真的在寻找一种方法来测试是否定义了函数装饰器,如果没有定义它,则无需在每次运行时都修改代码。丹尼尔的回答满足了这些要求。
      • @Laura,它确实是相同的变体,我很感激你不想修改代码。但是,我觉得对于那些想要手动控制并且不想检查/处理globals 列表的人来说,将其作为替代方案会很好。
      • 与其将其添加为单独的解决方案,不如考虑对原始解决方案进行评论,例如“嘿,丹尼尔,您可以将所有内容放在一行中,这样如果您想要手动注释掉就更容易了控制。”作为一个独立的解决方案,在某些情况下注释掉的代码似乎不是很优雅,因为它看起来真的很糟糕。这是我的意见。只是一个建议,无意冒犯,但我会否决这个答案,因为我个人讨厌在生产代码中看到注释掉的代码。
      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2020-07-11
      • 2020-11-03
      • 2016-01-06
      • 2017-10-21
      • 1970-01-01
      • 2014-04-14
      相关资源
      最近更新 更多