В основном я хочу использовать джедай для извлечения кода функции или кода из деталей его определений (путь, строка, колонка). Чтобы быть более явным, я действительно хочу получить код из файла, который не выполняется, статический.Получить код функции/класса из файла, знающего строку и столбец ее определения
ответ
Для решения этой задачи вы можете использовать ast
и codegen
.
Я буду размещать образец кода, чтобы проиллюстрировать это:
import ast,codegen
def find_by_line(root, line):
found = None
if hasattr(root, "lineno"):
if root.lineno == line:
return root
if hasattr(root, "body"):
for node in root.body:
found = find_by_line(node, line)
if found:
break
return found
def get_func_code(path, line):
with open(path) as file:
code_tree = ast.parse(file.read())
unit = find_by_line(code_tree, line)
return codegen.to_source(unit)
Благодаря @Erotemic за предложение 'ast', он практически дал мне решение. – khael
Я использую функцию find_pyfunc_above_row, определенную в этом файле https://github.com/Erotemic/utool/blob/next/utool/util_inspect.py, чтобы выполнить аналогичную задачу.
'find_pyfunc_above_row' получает имя функции, а для' get_func_sourcecode' мне нужна живая функция, мне нужна статическая функция поиска кода, никакого живого кода вообще. Использует ли 'utool' такую функциональность, или я что-то упускаю? – khael
Нет, я не думаю, что тебе что-то не хватает. Я думал, что функция сделала немного больше, чем она. Большая часть возможностей инспекции utool использует объекты живого кода. Тем не менее, вы могли бы использовать синтаксическое дерево для простого анализа файла после строки, в которой вы знаете, что функция включена, а затем захватить код из visit_FunctionDef. Взгляните на find_child_kwarg_funcs в том же файле, что делает статический анализ. Вы можете получить исходный код из дерева синтаксического анализа. – Erotemic
'ast' был хорошим выбором, он творит чудеса, спасибо. – khael
Это в настоящее время не то, что поддерживается в джедая. Вы могли бы это сделать, но не с публичным API. Есть две вещи, которые в настоящее время отсутствуют в API Jedi:
- Получение класса/функции по положению (вы можете получить это, играя с парсером джедая).
- Получение кода, когда у вас есть свой класс. Это очень просто:
node.get_code()
Попробуйте сыграть с jedi.parser.Parser
. Это довольно мощный инструмент, но пока еще не публиковался.
Хорошо. Тогда продолжай. –
@ DanielRoseman Я очень признателен, что вы готовы сэкономить немного времени, которое вам нужно, чтобы помочь мне. – khael