Source code for an eval'ed/dynamically generated function in Python
我正在寻找一种在运行时从包含源代码的字符串中创建python函数的方法,这种方法可以通过检查来获得源代码。
我目前的方法如下:
1 2 3 4 5 6 | src = 'def foo(x, y):' + ' \t' + 'return x / y' g = {numpy: numpy, ...} # Modules and such required for function l = {} exec(src, g, l) func = l['foo'] |
它工作得很好,但是函数没有与之相关的源代码/文件。这使得调试困难(请注意,在foo()中发生错误的行没有显示):
1 2 3 4 5 6 7 8 | >>> foo(1, 0) ZeroDivisionError Traceback (most recent call last) <ipython-input-85-9df128c5d862> in <module>() ----> 1 myfunc(3, 0) <string> in foo(x, y) ZeroDivisionError: division by zero |
如果我在ipython解释器中定义了一个函数,我可以使用
所以我通过挖掘ipython源代码部分地解决了这个问题。它利用了内置模块linecache,其中包含从文件中读取源代码和缓存结果的函数。
解决方案是以与问题相同的方式创建函数,但使用具有组成的唯一文件名的
1 2 3 4 5 6 7 8 9 10 | source = 'def foo(x, y):' + ' \t' + 'return x / y' filename = '<dynamic-123456>' # Angle brackets may be required? code = compile(source, filename, 'exec') g = {numpy: numpy, ...} # Modules and such required for function l = {} exec(src, g, l) func = l['foo'] |
1 2 3 4 5 | lines = [line + ' ' for line in source.splitlines()] import linecache linecache.cache[filename] = (len(source), None, lines, filename) |
然后该函数将与
编辑:请参阅下面的用户2357112的注释,了解如何在内置解释器中使用回溯打印。