如何确定函数(的源代码)是否包含循环? [英] How to find out if (the source code of) a function contains a loop?
问题描述
比方说,我有一堆函数a
、b
、c
、d
和e
我想知道他们是否直接使用循环:
Let's say, I have a bunch of functions a
, b
, c
, d
and e
and I want to find out if they directly use a loop:
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("
".join([str(i**2) for i in range(3)]))
def d():
print("
".join(["0", "1", "4"]))
def e():
"for"
我想编写一个函数 uses_loop
以便我可以期待这些断言通过:
I want to write a function uses_loop
so I can expect these assertions to pass:
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
使用列表推导而不是循环.)
(I expect uses_loop(c)
to return False
because c
uses a list comprehension instead of a loop.)
我无法修改a
、b
、c
、d
和e代码>.因此,我认为可以为此使用
ast
并沿用我从 inspect.getsource
获得的函数代码.但我对任何其他建议持开放态度,这只是它如何运作的一个想法.
I can't modify a
, b
, c
, d
and e
. So I thought it might be possible to use ast
for this and walk along the function's code which I get from inspect.getsource
. But I'm open to any other proposals, this was only an idea how it could work.
这是我用 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.For
或 ast 的实例.While
或 ast.AsyncFor
.您可以使用 ast.walk()
访问 AST 的每个节点
You need to check if the function's Abstract Syntaxt Tree has any nodes that are an instance of ast.For
or ast.While
or ast.AsyncFor
. You can use ast.walk()
to visit every node of the 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)
请参阅 ast
文档,async for
是 在 3.5 中添加.
See the documentation for ast
, async for
was added in 3.5.
这篇关于如何确定函数(的源代码)是否包含循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!