Как получить тип переменной из AST Python? - PullRequest
2 голосов
/ 08 декабря 2011

Предположим, я хочу получить тип всех переменных из дерева AST, которое я сгенерировал из некоторого исходного кода - как мне поступить?Например, предположим, в моем исходном коде у меня есть что-то вроде i = 5.Как определить из дерева абстрактного синтаксиса, что тип i является целым числом?

Я попробовал функцию type();однако в этой ситуации это не работает.

Ответы [ 3 ]

3 голосов
/ 08 декабря 2011

Как объяснено в других статьях, нет простого способа достичь этого без тщательного анализа синтаксического дерева, для которого модуль python ast не предоставляет никаких возможностей.

Вы все еще можете использовать astng logilab1 , который является основой для pylint 2 и предоставляет возможности статического вывода.

Вот краткий пример:

from logilab.astng.builder import ASTNGBuilder
builder = ASTNGBuilder()
astng = builder.string_build('i = 1', __name__, '<string>')
assnode = astng['']
print [(inf.value, type(inf.value)) for inf in assnode.infer()]

Конечно, выпридется копать API для более реального использования.Вы все еще можете написать python-projects@lists.logilab.org для помощи по этому вопросу.

2 голосов
/ 08 декабря 2011

Как отмечают другие авторы, в динамически типизированном языке это не так просто. Вы не можете просто отследить присвоение обратно до объявления статического типа, как вы можете это сделать в C или Java.

Однако, часто можно сделать разумное определение типа.

Предположительно, правила области видимости позволяют определить, к какому i (или к какому набору я) можно обращаться / обновлять / связывать, где задается вопрос («какой тип в этой точке в коде?»). Затем можно выполнить анализ всех значений, которые могут быть назначены (особенно тривиальный случай, когда я связан только с определением функции). Верхняя граница в решетке типов для этих типов является «типом» i. Да, это может быть «что угодно» в некоторых случаях, но в большинстве хорошо написанных программ даже динамические переменные имеют «узкий» тип, предназначенный программистом, и часто это примитивный тип языка (например, «int»). Или же программист не сможет написать разумный алгоритм (Что, ваш индекс массива иногда не является целым числом?).

Вам нужно провести какой-то консервативный анализ программы, чтобы определить этот тип верхней границы. (Очевидно, что вы можете сделать тривиальный анализ и сделать бесполезный вывод, что переменная может быть «любого» типа). Я думаю, что это неудовлетворительный ответ.

Механизм для выполнения всего этого анализа довольно сложен (вам нужен глобальный анализ потоков и некоторое определение того, что можно динамически загрузить, чтобы сделать это действительно хорошо), и я сомневаюсь, что пакет Python AST делает это.

0 голосов
/ 08 декабря 2011

Вы не можете, потому что переменные Python не имеют типа. Значения имеют типы.

Так работает динамическая типизация.

...