目标是检测某些代码中是否使用了内置函数,例如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
模块中。因此,1种方法将在types.FunctionType
调用中使用isinstance
。
但是因为我使用的是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'
如何正确识别代码中是否使用了特定的Buildin函数?谢谢!
答案 0 :(得分:1)
当您在代码中编写eval(whatever)
时,eval
会被普通的全局变量查找查找。您应该查找表示使用变量名ast.Name
的<{1}}节点:
eval
由于你有一个实际的函数对象,而不仅仅是源代码,你还可以检查影响内置函数的变量,这种变量比你刚才拥有该函数的源更可靠:/ p>
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.
)对内置访问做任何事情。它是否值得取决于你。