3

eval()目标是检测是否在某些代码中使用了诸如此类的内置函数。

def foo(a):
    eval('a = 2')

我尝试了以下方法:

ex_ast = ast.parse(inspect.getsource(foo))

for node in ast.walk(ex_ast):
if isinstance(node, ast.FunctionDef):
    print(node.name)

函数名称foo作为输出打印。

我知道内置函数没有构造函数。它们在type模块中。因此,一种方法将types.FunctionTypeisinstance通话中使用。

但是因为我使用的是 AST 节点。它们无法转换回代码。如果它们是,我必须检查每个节点types.FunctionType

for node in ast.walk(ex_ast):
    if isinstance(node, ast.FunctionType):
        print(node.name)

我得到了这些错误:

AttributeError: module 'ast' has no attribute 'FunctionType'

我应该如何正确识别代码中是否使用了特定的内置函数?谢谢!

4

1 回答 1

1

当你写eval(whatever)你的代码时,eval是通过一个普通的全局变量查找来查找的。您应该寻找一个ast.Name代表使用变量名称的节点 eval

for node in ast.walk(ex_ast):
    if isinstance(node, ast.Name) and node.id == 'eval':
        # Found it.

由于您有一个实际的函数对象,而不仅仅是源代码,因此您还可以以比仅拥有函数的源代码更可靠的方式检查隐藏内置函数的变量:

if ('eval' in foo.__code__.co_varnames     # local variable
    or 'eval' in foo.__code__.co_cellvars  # local variable used by nested function
    or 'eval' in foo.__code__.co_freevars  # local variable from enclosing function
    or 'eval' in foo.__globals__):         # global variable
    # Some variable is shadowing the built-in.

这不会捕获在检查之后添加的全局变量,并且它不会对通过不同名称(例如,)访问内置函数做任何事情x = eval; x('whatever')。值不值,就看你自己了。

于 2016-05-13T19:37:28.690 回答