Допустим, у меня есть набор функций a
, b
, c
, d
и e
, и я хочу выяснить, используют ли они непосредственно цикл:
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
использует понимание списка вместо цикла.)
Я не могу изменить a
, b
, c
, d
и e
. Поэтому я подумал, что для этого можно использовать 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__)