gpt4 book ai didi

python - 即时替换部分功能代码

转载 作者:行者123 更新时间:2023-11-30 23:41:10 25 4
gpt4 key购买 nike

Here我提出了我提出的另一个问题的解决方案,即如何删除分散在函数代码中的所有昂贵的调试输出函数调用(使用空函数 lambda *p: None 时速度减慢了 25 倍) )。

解决方案是动态编辑函数代码,并在所有函数调用前添加注释符号 #

from __future__ import print_function

DEBUG = False

def dprint(*args,**kwargs):
'''Debug print'''
print(*args,**kwargs)


def debug(on=False,string='dprint'):
'''Decorator to comment all the lines of the function code starting with string'''
def helper(f):
if not on:
import inspect
source = inspect.getsource(f)
source = source.replace(string, '#'+string) #Beware! Swithces off the whole line after dprint statement
with open('temp_f.py','w') as file:
file.write(source)
from temp_f import f as f_new
return f_new
else:
return f #return f intact
return helper


def f():
dprint('f() started')
print('Important output')
dprint('f() ended')

f = debug(DEBUG,'dprint')(f) #If decorator @debug(True) is used above f(), inspect.getsource somehow includes @debug(True) inside the code.

f()

我现在看到的问题是:

  • # 将所有行添加到末尾;但可能还有其他由 ; 分隔的语句。这可以通过删除 f 中的所有 pprint 调用而不是注释来解决,但它可能不是那么简单,因为可能有嵌套的括号。
  • 创建
  • temp_f.py,然后从中加载新的 f 代码。应该有一种更好的方法来做到这一点,而无需写入硬盘。我发现this recipe ,但还没有成功。
  • 如果装饰器应用了使用@debug的特殊语法,则inspect.getsource将带有装饰器的行包含到函数代码中。这一行可以手动从字符串中删除,但如果有多个装饰器应用于 f,则可能会导致错误。我通过使用旧式装饰器应用程序 f=decorator(f) 解决了这个问题。

您在这里还发现了什么其他问题?

如何解决所有这些问题?

这种方法的优点和缺点是什么?

这里有什么可以改进的地方?

有没有更好的方法来实现我尝试使用此代码实现的目标?

<小时/>

我认为在编译为字节码之前预处理函数代码是一种非常有趣且有争议的技术。但奇怪的是没有人对此感兴趣。我觉得我给出的代码可能有很多不稳定点。

最佳答案

装饰器可以返回包装器,也可以返回未更改的装饰函数。用它来创建更好的调试器:

from functools import wraps

def debug(enabled=False):
if not enabled:
return lambda x: x # Noop, returns decorated function unaltered

def debug_decorator(f):
@wraps(f)
def print_start(*args, **kw):
print('{0}() started'.format(f.__name__))
try:
return f(*args, **kw)
finally:
print('{0}() completed'.format(f.__name__))
return print_start
return debug_decorator

debug 函数是一个装饰器工厂,调用时它会生成一个装饰器函数。如果禁用调试,它只会返回一个 lambda,该 lambda 不改变其参数,即一个无操作装饰器。启用调试时,它会返回一个调试装饰器,该装饰器在装饰函数启动时打印,并在返回时再次打印。

然后将返回的装饰器应用于装饰函数。

用法:

DEBUG = True

@debug(DEBUG)
def my_function_to_be_tested():
print('Hello world!')

重申一下:当 DEBUG 设置为 false 时,my_function_to_be_tested 保持不变,因此运行时性能根本不受影响。

关于python - 即时替换部分功能代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12229424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com