Chr*_*ris 7 python abstract-syntax-tree
这似乎应该很容易,但我无法在任何地方找到答案 - 也无法自己派生出答案.你如何将未引用的python函数/ lambda转换为AST?
这是我希望能够做到的.
import ast
class Walker(ast.NodeVisitor):
pass
# ...
# note, this doesnt work as ast.parse wants a string
tree = ast.parse(lambda x,y: x+y)
Walker().visit(tree)
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 10
一般来说,你不能.例如,2 + 2是一个表达式 - 但是如果将它传递给任何函数或方法,传递的参数只是数字4,无法恢复计算它的表达式.函数源代码有时可以被恢复(虽然不是为了lambda),但是"一个不带引号的Python表达式"被评估,所以你得到的只是表达式值的对象.
你想解决什么问题?可能还有其他可行的方法.
编辑:tx到OP澄清.没有办法为它lambda或其他一些角落情况做,但正如我提到的功能源代码有时可以恢复......:
import ast
import inspect
def f():
return 23
tree = ast.parse(inspect.getsource(f))
print ast.dump(tree)
Run Code Online (Sandbox Code Playgroud)
inspect.getsourceIOError如果无法获取您传递的任何对象的源代码,则会引发此问题.我建议你将解析和getsource调用包装成一个辅助函数,它可以接受一个字符串(并且只是解析它)或一个函数(并尝试获取它的源代码,可能在这种IOError情况下给出更好的错误).
如果只能访问函数/ lambda,那么只有编译的python字节码.无法从字节码重构精确的Python AST,因为编译过程中存在信息丢失.但是你可以分析字节码并为此创建AST.GeniuSQL中有一个这样的分析器.我还有一个小概念证明,它分析字节码并从中创建SQLAlchemy子元素.
我用于分析的过程如下:
我已经使用它粘贴了我的概念证明和示例代码.这是非干净的快速入侵代码,但如果你愿意,你可以自由地构建它.如果你决定用它做一些有用的东西,请留言.
小智 5
元库允许您在许多情况下恢复源,但有一些例外,例如comprehensions和lambdas.
import meta, ast
source = '''
a = 1
b = 2
c = (a ** b)
'''
mod = ast.parse(source, '<nofile>', 'exec')
code = compile(mod, '<nofile>', 'exec')
mod2 = meta.decompile(code)
source2 = meta.dump_python_source(mod2)
assert source == source2
Run Code Online (Sandbox Code Playgroud)