kompletności boską, chciałbym podkreślić, że czasami może chcesz kodu parse zamiast importować je. Wyrażenia najwyższego poziomu mogą być wykonywane przy użyciu import
i może to stanowić problem.
Na przykład, pozwalam użytkownikom wybierać funkcje punktu wejścia dla pakietów tworzonych przy użyciu zipapp. Korzystanie z ryzykownego kodu, prowadzącego do awarii, pomoc w drukowaniu komunikatów, pojawianie się okien dialogowych GUI i tak dalej.
Zamiast korzystać z modułu ast do listy wszystkich funkcji najwyższego poziomu:
import ast
import sys
def top_level_functions(body):
return (f for f in body if isinstance(f, ast.FunctionDef))
def parse_ast(filename):
with open(filename, "rt") as file:
return ast.parse(file.read(), filename=filename)
if __name__ == "__main__":
for filename in sys.argv[1:]:
print(filename)
tree = parse_ast(filename)
for func in top_level_functions(tree.body):
print(" %s" % func.name)
Umieszczenie tego kodu w list.py
i stosując się jako dane wejściowe, otrzymuję:
$ python list.py list.py
list.py
top_level_functions
parse_ast
Oczywiście, nawigacja w AST może być czasem trudna, nawet w przypadku stosunkowo prostego języka, takiego jak Python, ponieważ AST jest dość niski. Ale jeśli masz prosty i przejrzysty przypadek użycia, jest to wykonalne i bezpieczne.
Jednak wadą jest to, że nie można wykryć funkcji generowanych w czasie wykonywania, takich jak foo = lambda x,y: x*y
.
proszę rozważyć przejrzenie wybranej odpowiedzi! istnieją lepsze/łatwiejsze w użyciu rozwiązania sugerowane w innych odpowiedziach. – r2d2oid