在这里,我想出了解决我提出的另一个问题的解决方案,该问题是如何删除分散在函数代码中的所有昂贵的调试输出函数调用(使用空函数时减速是 25 倍lambda *p: None
)。
解决方案是动态编辑函数代码并在所有函数调用前加上注释符号#
。
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()
我现在看到的问题是:
#
commets 所有行到最后;但可能还有其他语句以 . 分隔;
。这可以通过删除所有pprint
调用来解决f
,而不是评论,但它可能不是那么微不足道,因为可能存在嵌套的括号。temp_f.py
被创建,然后f
从中加载新代码。应该有更好的方法来做到这一点,而无需写入硬盘驱动器。我找到了这个食谱,但没能成功。- 如果使用特殊语法应用装饰器,
@debug
则inspect.getsource
在函数代码中包含带有装饰器的行。此行可以手动从字符串中删除,但如果有多个装饰器应用于f
. 我通过使用旧式装饰器应用程序解决了这个问题f=decorator(f)
。
您在这里看到了哪些其他问题?
如何解决所有这些问题?
这种方法的优点和缺点是什么?
这里有什么可以改进的?
有没有更好的方法来做我试图用这段代码实现的目标?
我认为在编译为字节码之前预处理函数代码是一种非常有趣且有争议的技术。奇怪的是没有人对此感兴趣。我认为我给出的代码可能有很多不可靠的地方。