python - 如何找出函数(的源代码)是否包含循环?

标签 python loops abstract-syntax-tree static-analysis inspect

比方说,我有一堆函数 abcde 我想知道他们是否直接使用循环:

def a():
    for i in range(3):
        print(i**2)

def b():
    i = 0
    while i < 3:
        print(i**2)
        i += 1

def c():
    print("\n".join([str(i**2) for i in range(3)]))

def d():
    print("\n".join(["0", "1", "4"]))

def e():
    "for"

我想写一个函数 uses_loop 这样我就可以期望这些断言通过:

assert uses_loop(a) == True
assert uses_loop(b) == True
assert uses_loop(c) == False
assert uses_loop(d) == False
assert uses_loop(e) == False

(我希望 uses_loop(c) 返回 False,因为 c 使用列表理解而不是循环。)

我无法修改abcde。所以我认为可以为此使用 ast 并遍历从 inspect.getsource 获得的函数代码。 但我对任何其他建议持开放态度,这只是一个想法。

这就是我使用ast所做的:

def uses_loop(function):
    import ast
    import inspect
    nodes = ast.walk(ast.parse(inspect.getsource(function)))
    for node in nodes:
        print(node.__dict__)

最佳答案

您需要检查函数的抽象语法树是否有任何节点是 ast.Forast.Whileast.AsyncFor< 的实例。您可以使用 ast.walk()访问AST的每个节点

import ast
import inspect

def uses_loop(function):
    loop_statements = ast.For, ast.While, ast.AsyncFor

    nodes = ast.walk(ast.parse(inspect.getsource(function)))
    return any(isinstance(node, loop_statements) for node in nodes)

参见 documentation for ast , async foradded in 3.5 .

关于python - 如何找出函数(的源代码)是否包含循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54092879/

相关文章:

c - openMP 线程和迭代

c++ - 我不明白为什么这个 while 循环是无止境的

javascript - 识别 Javascript 对象中的最后一次迭代

macros - 如何使用准引用来获取 Nemerle 中的 AST?

python - Django 中未知 max_length 的最佳实践?

python - 我如何在 Python 中接收来自 IBs API 的数据?

python - 为什么我的 if 语句在正确时没有被调用?

python - 如何使用 python diff_match_patch 创建补丁并应用

java.lang.NoSuchFieldError : resources - Eclipse AST parser error

python - 使用 python 将文件读取为 json 的替代方法