ast — Абстрактные синтаксические деревья
Исходный код: Lib/ast.py
Модуль ast помогает приложениям Python обрабатывать деревья абстрактной синтаксической грамматики Python. Сама абстрактная грамматика может меняться с каждым выпуском Python; этот модуль помогает программно выяснить, как выглядит текущая грамматика.
Абстрактное синтаксическое дерево можно создать, передав ast.PyCF_ONLY_AST в качестве флага встроенной функции compile() или воспользовавшись вспомогательной функцией parse(), предоставляемой этим модулем. Результатом будет дерево объектов, классы которых наследуются от ast.AST. Абстрактное синтаксическое дерево можно скомпилировать в объект кода Python с помощью встроенной функции compile().
Абстрактная грамматика
В настоящее время абстрактная грамматика определена следующим образом:
-- ASDL's 4 builtin types are:
-- identifier, int, string, constant
module Python
{
mod = Module(stmt* body, type_ignore* type_ignores)
| Interactive(stmt* body)
| Expression(expr body)
| FunctionType(expr* argtypes, expr returns)
stmt = FunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment, type_param* type_params)
| AsyncFunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment, type_param* type_params)
| ClassDef(identifier name,
expr* bases,
keyword* keywords,
stmt* body,
expr* decorator_list,
type_param* type_params)
| Return(expr? value)
| Delete(expr* targets)
| Assign(expr* targets, expr value, string? type_comment)
| TypeAlias(expr name, type_param* type_params, expr value)
| AugAssign(expr target, operator op, expr value)
-- 'simple' indicates that we annotate simple name without parens
| AnnAssign(expr target, expr annotation, expr? value, int simple)
-- use 'orelse' because else is a keyword in target languages
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| While(expr test, stmt* body, stmt* orelse)
| If(expr test, stmt* body, stmt* orelse)
| With(withitem* items, stmt* body, string? type_comment)
| AsyncWith(withitem* items, stmt* body, string? type_comment)
| Match(expr subject, match_case* cases)
| Raise(expr? exc, expr? cause)
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| Assert(expr test, expr? msg)
| Import(alias* names)
| ImportFrom(identifier? module, alias* names, int? level)
| Global(identifier* names)
| Nonlocal(identifier* names)
| Expr(expr value)
| Pass | Break | Continue
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- BoolOp() can use left & right?
expr = BoolOp(boolop op, expr* values)
| NamedExpr(expr target, expr value)
| BinOp(expr left, operator op, expr right)
| UnaryOp(unaryop op, expr operand)
| Lambda(arguments args, expr body)
| IfExp(expr test, expr body, expr orelse)
| Dict(expr* keys, expr* values)
| Set(expr* elts)
| ListComp(expr elt, comprehension* generators)
| SetComp(expr elt, comprehension* generators)
| DictComp(expr key, expr value, comprehension* generators)
| GeneratorExp(expr elt, comprehension* generators)
-- the grammar constrains where yield expressions can occur
| Await(expr value)
| Yield(expr? value)
| YieldFrom(expr value)
-- need sequences for compare to distinguish between
-- x < 4 < 3 and (x < 4) < 3
| Compare(expr left, cmpop* ops, expr* comparators)
| Call(expr func, expr* args, keyword* keywords)
| FormattedValue(expr value, int conversion, expr? format_spec)
| JoinedStr(expr* values)
| Constant(constant value, string? kind)
-- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx)
| Subscript(expr value, expr slice, expr_context ctx)
| Starred(expr value, expr_context ctx)
| Name(identifier id, expr_context ctx)
| List(expr* elts, expr_context ctx)
| Tuple(expr* elts, expr_context ctx)
-- can appear only in Subscript
| Slice(expr? lower, expr? upper, expr? step)
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
expr_context = Load | Store | Del
boolop = And | Or
operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift
| RShift | BitOr | BitXor | BitAnd | FloorDiv
unaryop = Invert | Not | UAdd | USub
cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
comprehension = (expr target, expr iter, expr* ifs, int is_async)
excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs,
expr* kw_defaults, arg? kwarg, expr* defaults)
arg = (identifier arg, expr? annotation, string? type_comment)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- keyword arguments supplied to call (NULL identifier for **kwargs)
keyword = (identifier? arg, expr value)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
withitem = (expr context_expr, expr? optional_vars)
match_case = (pattern pattern, expr? guard, stmt* body)
pattern = MatchValue(expr value)
| MatchSingleton(constant value)
| MatchSequence(pattern* patterns)
| MatchMapping(expr* keys, pattern* patterns, identifier? rest)
| MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)
| MatchStar(identifier? name)
-- The optional "rest" MatchMapping parameter handles capturing extra mapping keys
| MatchAs(pattern? pattern, identifier? name)
| MatchOr(pattern* patterns)
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
type_ignore = TypeIgnore(int lineno, string tag)
type_param = TypeVar(identifier name, expr? bound)
| ParamSpec(identifier name)
| TypeVarTuple(identifier name)
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
}
Классы узлов
-
class ast.AST -
Это базовый класс всех классов узлов AST. Фактические классы узлов получены из файла
Parser/Python.asdl, который воспроизведён выше. Они определены в модуле C_astи повторно экспортированы вast.Для каждого символа в левой части абстрактной грамматики определён отдельный класс (например,
ast.stmtилиast.expr). Кроме того, для каждой конструкции в правой части определён отдельный класс; эти классы наследуются от классов деревьев из левой части. Например,ast.BinOpнаследуется отast.expr. Для правил продукции с альтернативами (так называемыми «суммами») класс левой части является абстрактным: создаются только экземпляры конкретных узлов-конструкторов.-
_fields -
У каждого конкретного класса есть атрибут
_fields, содержащий имена всех дочерних узлов.У каждого экземпляра конкретного класса есть по одному атрибуту для каждого дочернего узла; их типы определены в грамматике. Например, у экземпляров
ast.BinOpесть атрибутleftтипаast.expr.Если в грамматике эти атрибуты помечены как необязательные (с помощью вопросительного знака), их значением может быть
None. Если атрибуты могут содержать ноль или более значений (обозначенных звёздочкой), значения представлены списками Python. При компиляции AST с помощьюcompile()все возможные атрибуты должны присутствовать и иметь допустимые значения.
-
lineno -
col_offset -
end_lineno -
end_col_offset -
У экземпляров
ast.exprи подклассовast.stmtесть атрибутыlineno,col_offset,end_linenoиend_col_offset. Атрибутыlinenoиend_linenoсодержат номера первой и последней строк фрагмента исходного текста (нумерация начинается с 1, поэтому первая строка — строка 1), а атрибутыcol_offsetиend_col_offsetсодержат соответствующие смещения в байтах UTF-8 для первого и последнего токенов, породивших узел. Смещение в UTF-8 сохраняется, поскольку парсер внутри использует UTF-8.Обратите внимание, что конечные позиции не требуются компилятору и поэтому являются необязательными. Конечное смещение указывает на позицию после последнего символа; например, с помощью
source_line[node.col_offset : node.end_col_offset]можно получить фрагмент исходного кода для узла однострочного выражения.
Конструктор класса
ast.Tразбирает аргументы следующим образом:- Если переданы позиционные аргументы, их количество должно совпадать с количеством элементов в
T._fields; они будут присвоены атрибутам с соответствующими именами. - Если переданы именованные аргументы, они зададут значения атрибутов с такими же именами.
Например, чтобы создать и заполнить узел
ast.UnaryOp, можно использоватьnode = ast.UnaryOp() node.op = ast.USub() node.operand = ast.Constant() node.operand.value = 5 node.operand.lineno = 0 node.operand.col_offset = 0 node.lineno = 0 node.col_offset = 0
или более компактный вариант
node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0) -
Изменено в версии 3.8: Теперь для всех констант используется класс ast.Constant.
Изменено в версии 3.9: Простые индексы представлены своими значениями, расширенные срезы — кортежами.
Устарело с версии 3.8: Старые классы ast.Num, ast.Str, ast.Bytes, ast.NameConstant и ast.Ellipsis пока доступны, но будут удалены в будущих выпусках Python. До этого времени при их создании будет возвращаться экземпляр другого класса.
Устарело с версии 3.9: Старые классы ast.Index и ast.ExtSlice пока доступны, но будут удалены в будущих выпусках Python. До этого времени при их создании будет возвращаться экземпляр другого класса.
Примечание
Описания конкретных классов узлов, приведённые здесь, изначально были адаптированы из замечательного проекта Green Tree Snakes и материалов его участников.
Корневые узлы
-
class ast.Module(body, type_ignores) -
Модуль Python, соответствующий вводу файла. Тип узла, создаваемый функцией
ast.parse()в режиме"exec"по умолчанию.body— этоlistоператоров модуля, см. раздел Операторы.type_ignores— этоlistкомментариев модуля об игнорировании типов; подробности см. в описанииast.parse().>>> print(ast.dump(ast.parse('x = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1))], type_ignores=[])
-
class ast.Expression(body) -
Отдельное выражение на входе Python. Тип узла, создаваемый функцией
ast.parse(), если значение mode —"eval".body— это отдельный узел, один из типов выражений.>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
-
class ast.Interactive(body) -
Отдельный интерактивный ввод, например, в интерактивном режиме. Тип узла, создаваемый функцией
ast.parse(), если значение mode —"single".body— этоlistузлов операторов.>>> print(ast.dump(ast.parse('x = 1; y = 2', mode='single'), indent=4)) Interactive( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1)), Assign( targets=[ Name(id='y', ctx=Store())], value=Constant(value=2))])
-
class ast.FunctionType(argtypes, returns) -
Представление комментариев типов старого формата для функций, поскольку версии Python до 3.5 не поддерживали аннотации PEP 484. Тип узла, создаваемый функцией
ast.parse(), если значение mode —"func_type".Такие комментарии типов выглядели бы следующим образом:
def sum_two_number(a, b): # type: (int, int) -> int return a + bargtypes— этоlistузлов выражений.returns— это отдельный узел выражения.>>> print(ast.dump(ast.parse('(int, str) -> List[int]', mode='func_type'), indent=4)) FunctionType( argtypes=[ Name(id='int', ctx=Load()), Name(id='str', ctx=Load())], returns=Subscript( value=Name(id='List', ctx=Load()), slice=Name(id='int', ctx=Load()), ctx=Load()))Добавлено в версии 3.8.
Литералы
-
class ast.Constant(value) -
Постоянное значение. Атрибут
valueлитералаConstantсодержит представляемый им объект Python. Представленные значения могут быть простыми типами, такими как число, строка илиNone, а также неизменяемыми контейнерами (кортежами и frozenset), если все их элементы являются константами.>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
-
class ast.FormattedValue(value, conversion, format_spec) -
Узел, представляющий одно поле форматирования в f-строке. Если строка содержит только одно поле форматирования и больше ничего, узел может быть изолирован; в противном случае он входит в состав
JoinedStr.-
value— любой узел выражения (например, литерал, переменная или вызов функции). -
conversion— целое число:- -1: без форматирования
- 115: форматирование строки
!s - 114: форматирование представления
!r - 97: форматирование ASCII
!a
-
format_spec— узелJoinedStr, представляющий форматирование значения, илиNone, если формат не указан.conversionиformat_specмогут быть заданы одновременно.
-
-
class ast.JoinedStr(values) -
f-строка, состоящая из последовательности узлов
FormattedValueиConstant.>>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4)) Expression( body=JoinedStr( values=[ Constant(value='sin('), FormattedValue( value=Name(id='a', ctx=Load()), conversion=-1), Constant(value=') is '), FormattedValue( value=Call( func=Name(id='sin', ctx=Load()), args=[ Name(id='a', ctx=Load())], keywords=[]), conversion=-1, format_spec=JoinedStr( values=[ Constant(value='.3')]))]))
-
class ast.List(elts, ctx) -
class ast.Tuple(elts, ctx) -
Список или кортеж.
eltsсодержит список узлов, представляющих элементы.ctxимеет значениеStore, если контейнер является целью присваивания (то есть(x,y)=something), иLoadв противном случае.>>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4)) Expression( body=List( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load())) >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4)) Expression( body=Tuple( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load()))
-
class ast.Set(elts) -
Множество.
eltsсодержит список узлов, представляющих элементы множества.>>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4)) Expression( body=Set( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)]))
-
class ast.Dict(keys, values) -
Словарь.
keysиvaluesсодержат списки узлов, представляющих ключи и значения соответственно, в соответствующем порядке (то, что вернули бы вызовыdictionary.keys()иdictionary.values()).При распаковке словаря с помощью литералов словаря раскрываемое выражение помещается в список
values, а на соответствующей позиции вkeysуказываетсяNone.>>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4)) Expression( body=Dict( keys=[ Constant(value='a'), None], values=[ Constant(value=1), Name(id='d', ctx=Load())]))
Переменные
-
class ast.Name(id, ctx) -
Имя переменной.
idсодержит имя в виде строки, аctxпринимает одно из следующих значений.
-
class ast.Load -
class ast.Store -
class ast.Del -
Ссылки на переменные могут использоваться для получения значения переменной, присваивания ей нового значения или её удаления. Чтобы различать эти случаи, ссылкам на переменные задаётся контекст.
>>> print(ast.dump(ast.parse('a'), indent=4)) Module( body=[ Expr( value=Name(id='a', ctx=Load()))], type_ignores=[]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])], type_ignores=[])
-
class ast.Starred(value, ctx) -
Ссылка на переменную с
*var.valueсодержит переменную, обычно узелName. Этот тип необходимо использовать при создании узлаCallс*args.>>> print(ast.dump(ast.parse('a, *b = it'), indent=4)) Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Starred( value=Name(id='b', ctx=Store()), ctx=Store())], ctx=Store())], value=Name(id='it', ctx=Load()))], type_ignores=[])
Выражения
-
class ast.Expr(value) -
Если выражение, например вызов функции, используется как самостоятельный оператор, а его возвращаемое значение не используется и не сохраняется, оно оборачивается в этот контейнер.
valueсодержит один из других узлов этого раздела:Constant,Name,Lambda,Yieldили узелYieldFrom.>>> print(ast.dump(ast.parse('-a'), indent=4)) Module( body=[ Expr( value=UnaryOp( op=USub(), operand=Name(id='a', ctx=Load())))], type_ignores=[])
-
class ast.UnaryOp(op, operand) -
Унарная операция.
op— это оператор, аoperand— любой узел выражения.
-
class ast.UAdd -
class ast.USub -
class ast.Not -
class ast.Invert -
Токены унарных операторов.
Not— это ключевое словоnot,Invert— оператор~.>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4)) Expression( body=UnaryOp( op=Not(), operand=Name(id='x', ctx=Load())))
-
class ast.BinOp(left, op, right) -
Бинарная операция (например, сложение или деление).
op— это оператор, аleftиright— любые узлы выражения.>>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4)) Expression( body=BinOp( left=Name(id='x', ctx=Load()), op=Add(), right=Name(id='y', ctx=Load())))
-
class ast.Add -
class ast.Sub -
class ast.Mult -
class ast.Div -
class ast.FloorDiv -
class ast.Mod -
class ast.Pow -
class ast.LShift -
class ast.RShift -
class ast.BitOr -
class ast.BitXor -
class ast.BitAnd -
class ast.MatMult -
Токены бинарных операторов.
-
class ast.BoolOp(op, values) -
Логическая операция «или» либо «и».
op— этоOrилиAnd.values— это участвующие в операции значения. Последовательные операции с одним и тем же оператором, напримерa or b or c, объединяются в один узел с несколькими значениями.Это не относится к
not, которое представляет собойUnaryOp.>>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4)) Expression( body=BoolOp( op=Or(), values=[ Name(id='x', ctx=Load()), Name(id='y', ctx=Load())]))
-
class ast.And -
class ast.Or -
Токены логических операторов.
-
class ast.Compare(left, ops, comparators) -
Сравнение двух или более значений.
left— первое значение в сравнении,ops— список операторов, аcomparators— список значений после первого элемента сравнения.>>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4)) Expression( body=Compare( left=Constant(value=1), ops=[ LtE(), Lt()], comparators=[ Name(id='a', ctx=Load()), Constant(value=10)]))
-
class ast.Eq -
class ast.NotEq -
class ast.Lt -
class ast.LtE -
class ast.Gt -
class ast.GtE -
class ast.Is -
class ast.IsNot -
class ast.In -
class ast.NotIn -
Токены операторов сравнения.
-
class ast.Call(func, args, keywords) -
Вызов функции.
func— это функция, часто представленная объектомNameилиAttribute. Аргументы:-
argsсодержит список аргументов, переданных позиционно. -
keywordsсодержит список объектовkeyword, представляющих аргументы, переданные по ключевым словам.
При создании узла
Callобязательныargsиkeywords, однако они могут быть пустыми списками.>>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4)) Expression( body=Call( func=Name(id='func', ctx=Load()), args=[ Name(id='a', ctx=Load()), Starred( value=Name(id='d', ctx=Load()), ctx=Load())], keywords=[ keyword( arg='b', value=Name(id='c', ctx=Load())), keyword( value=Name(id='e', ctx=Load()))])) -
-
class ast.keyword(arg, value) -
Аргумент, заданный по ключевому слову, при вызове функции или определении класса.
arg— это обычная строка с именем параметра, аvalue— узел, передаваемый в качестве аргумента.
-
class ast.IfExp(test, body, orelse) -
Выражение, например
a if b else c. Каждое поле содержит отдельный узел, поэтому в следующем примере все три узла являются узламиName.>>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4)) Expression( body=IfExp( test=Name(id='b', ctx=Load()), body=Name(id='a', ctx=Load()), orelse=Name(id='c', ctx=Load())))
-
class ast.Attribute(value, attr, ctx) -
Доступ к атрибуту, например
d.keys.value— это узел, обычноName.attr— обычная строка с именем атрибута, аctxимеет значениеLoad,StoreилиDelв зависимости от выполняемого с атрибутом действия.>>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4)) Expression( body=Attribute( value=Name(id='snake', ctx=Load()), attr='colour', ctx=Load()))
-
class ast.NamedExpr(target, value) -
Именованное выражение. Этот узел AST создаётся оператором присваивания-выражения (также известным как оператор-морж). В отличие от узла
Assign, в котором первый аргумент может состоять из нескольких узлов, здесь иtarget, иvalueдолжны быть отдельными узлами.>>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4)) Expression( body=NamedExpr( target=Name(id='x', ctx=Store()), value=Constant(value=4)))Добавлено в версии 3.8.
Индексация
-
class ast.Subscript(value, slice, ctx) -
Индексация, например
l[1].value— объект, к которому применяется индексация (обычно последовательность или отображение).slice— индекс, срез или ключ. Это может бытьTuple, содержащийSlice.ctxимеет значениеLoad,StoreилиDelв зависимости от действия, выполняемого с индексируемым объектом.>>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Tuple( elts=[ Slice( lower=Constant(value=1), upper=Constant(value=2)), Constant(value=3)], ctx=Load()), ctx=Load()))
-
class ast.Slice(lower, upper, step) -
Обычный срез (в форме
lower:upperилиlower:upper:step). Может встречаться только в поле slice узлаSubscript: непосредственно или как элементTuple.>>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Slice( lower=Constant(value=1), upper=Constant(value=2)), ctx=Load()))
Включения
-
class ast.ListComp(elt, generators) -
class ast.SetComp(elt, generators) -
class ast.GeneratorExp(elt, generators) -
class ast.DictComp(key, value, generators) -
Включения списков и множеств, генераторные выражения и включения словарей.
elt(илиkeyиvalue) — отдельный узел, представляющий часть, которая будет вычисляться для каждого элемента.generators— список узловcomprehension.>>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4)) Expression( body=ListComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4)) Expression( body=DictComp( key=Name(id='x', ctx=Load()), value=BinOp( left=Name(id='x', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4)) Expression( body=SetComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)]))
-
class ast.comprehension(target, iter, ifs, is_async) -
Одно предложение
forво включении.target— ссылка, используемая для каждого элемента; обычно это узелNameилиTuple.iter— объект, по которому выполняется итерация.ifs— список проверочных выражений: каждое предложениеforможет содержать несколькоifs.is_asyncуказывает, что включение является асинхронным (используетсяasync forвместоfor). Значение — целое число (0 или 1).>>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'), ... indent=4)) # Multiple comprehensions in one. Expression( body=ListComp( elt=Call( func=Name(id='ord', ctx=Load()), args=[ Name(id='c', ctx=Load())], keywords=[]), generators=[ comprehension( target=Name(id='line', ctx=Store()), iter=Name(id='file', ctx=Load()), ifs=[], is_async=0), comprehension( target=Name(id='c', ctx=Store()), iter=Name(id='line', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('(n**2 for n in it if n>5 if n<10)', mode='eval'), ... indent=4)) # generator comprehension Expression( body=GeneratorExp( elt=BinOp( left=Name(id='n', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='n', ctx=Store()), iter=Name(id='it', ctx=Load()), ifs=[ Compare( left=Name(id='n', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), Compare( left=Name(id='n', ctx=Load()), ops=[ Lt()], comparators=[ Constant(value=10)])], is_async=0)])) >>> print(ast.dump(ast.parse('[i async for i in soc]', mode='eval'), ... indent=4)) # Async comprehension Expression( body=ListComp( elt=Name(id='i', ctx=Load()), generators=[ comprehension( target=Name(id='i', ctx=Store()), iter=Name(id='soc', ctx=Load()), ifs=[], is_async=1)]))
Инструкции
-
class ast.Assign(targets, value, type_comment) -
Присваивание.
targets— это список узлов, аvalue— один узел.Несколько узлов в
targetsозначают присваивание одного и того же значения каждому из них. Распаковка представляется помещениемTupleилиListвtargets.-
type_comment -
type_comment— это необязательная строка с аннотацией типа в виде комментария.
>>> print(ast.dump(ast.parse('a = b = 1'), indent=4)) # Multiple assignment Module( body=[ Assign( targets=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('a,b = c'), indent=4)) # Unpacking Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store())], value=Name(id='c', ctx=Load()))], type_ignores=[]) -
-
class ast.AnnAssign(target, annotation, value, simple) -
Присваивание с аннотацией типа.
target— это один узел, которым может бытьName,AttributeилиSubscript.annotation— это аннотация, например узелConstantилиName.value— это один необязательный узел.simpleвсегда равно 0 (указывает на «сложную» цель) или 1 (указывает на «простую» цель). «Простая» цель состоит только из узлаName, не заключённого в скобки; все остальные цели считаются сложными. Только простые цели появляются в словаре__annotations__модулей и классов.>>> print(ast.dump(ast.parse('c: int'), indent=4)) Module( body=[ AnnAssign( target=Name(id='c', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=1)], type_ignores=[]) >>> print(ast.dump(ast.parse('(a): int = 1'), indent=4)) # Annotation with parenthesis Module( body=[ AnnAssign( target=Name(id='a', ctx=Store()), annotation=Name(id='int', ctx=Load()), value=Constant(value=1), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a.b: int'), indent=4)) # Attribute annotation Module( body=[ AnnAssign( target=Attribute( value=Name(id='a', ctx=Load()), attr='b', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation Module( body=[ AnnAssign( target=Subscript( value=Name(id='a', ctx=Load()), slice=Constant(value=1), ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[])
-
class ast.AugAssign(target, op, value) -
Расширенное присваивание, например
a += 1. В следующем примереtarget— это узелNameдляx(с контекстомStore),op— этоAdd, аvalue— этоConstantсо значением 1.Атрибут
targetне может быть экземпляром классаTupleилиList, в отличие от целейAssign.>>> print(ast.dump(ast.parse('x += 2'), indent=4)) Module( body=[ AugAssign( target=Name(id='x', ctx=Store()), op=Add(), value=Constant(value=2))], type_ignores=[])
-
class ast.Raise(exc, cause) -
Инструкция
raise.exc— это объект исключения, которое нужно вызвать; обычно этоCallилиName, либоNoneдля самостоятельной инструкцииraise.cause— необязательная часть дляyвraise x from y.>>> print(ast.dump(ast.parse('raise x from y'), indent=4)) Module( body=[ Raise( exc=Name(id='x', ctx=Load()), cause=Name(id='y', ctx=Load()))], type_ignores=[])
-
class ast.Assert(test, msg) -
Проверочное утверждение.
testсодержит условие, например узелCompare.msgсодержит сообщение об ошибке.>>> print(ast.dump(ast.parse('assert x,y'), indent=4)) Module( body=[ Assert( test=Name(id='x', ctx=Load()), msg=Name(id='y', ctx=Load()))], type_ignores=[])
-
class ast.Delete(targets) -
Представляет инструкцию
del.targets— это список узлов, таких как узлыName,AttributeилиSubscript.>>> print(ast.dump(ast.parse('del x,y,z'), indent=4)) Module( body=[ Delete( targets=[ Name(id='x', ctx=Del()), Name(id='y', ctx=Del()), Name(id='z', ctx=Del())])], type_ignores=[])
-
class ast.Pass -
Инструкция
pass.>>> print(ast.dump(ast.parse('pass'), indent=4)) Module( body=[ Pass()], type_ignores=[])
-
class ast.TypeAlias(name, type_params, value) -
Псевдоним типа, созданный с помощью инструкции
type.name— это имя псевдонима,type_params— список параметров типа, аvalue— значение псевдонима типа.>>> print(ast.dump(ast.parse('type Alias = int'), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[], value=Name(id='int', ctx=Load()))], type_ignores=[])Добавлено в версии 3.12.
Другие инструкции, применимые только внутри функций или циклов, описаны в других разделах.
Импорт
-
class ast.Import(names) -
Инструкция импорта.
names— это список узловalias.>>> print(ast.dump(ast.parse('import x,y,z'), indent=4)) Module( body=[ Import( names=[ alias(name='x'), alias(name='y'), alias(name='z')])], type_ignores=[])
-
class ast.ImportFrom(module, names, level) -
Представляет
from x import y.module— это строка с исходным именем после ‘from’, без начальных точек, либоNoneдля таких инструкций, какfrom . import foo.level— целое число, указывающее уровень относительного импорта (0 означает абсолютный импорт).>>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4)) Module( body=[ ImportFrom( module='y', names=[ alias(name='x'), alias(name='y'), alias(name='z')], level=0)], type_ignores=[])
-
class ast.alias(name, asname) -
Оба параметра содержат исходные строки с именами.
asnameможет быть равенNone, если нужно использовать исходное имя.>>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4)) Module( body=[ ImportFrom( module='foo.bar', names=[ alias(name='a', asname='b'), alias(name='c')], level=2)], type_ignores=[])
Управление потоком выполнения
Примечание
Необязательные части, такие как else, представлены пустым списком, если они отсутствуют.
-
class ast.If(test, body, orelse) -
Инструкция
if.testсодержит один узел, например узелCompare.bodyиorelseсодержат списки узлов.Части
elifне имеют в AST специального представления, а представлены дополнительными узламиIfв разделеorelseпредыдущего узла.>>> print(ast.dump(ast.parse(""" ... if x: ... ... ... elif y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ If( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ If( test=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
-
class ast.For(target, iter, body, orelse, type_comment) -
Цикл
for.targetсодержит переменную или переменные, которым цикл присваивает значения, в виде одного узлаName,Tuple,List,AttributeилиSubscript.iterсодержит элемент, по которому выполняется итерация, также в виде одного узла.bodyиorelseсодержат списки узлов для выполнения. Узлы изorelseвыполняются, если цикл завершился обычным образом, а не с помощью инструкцииbreak.-
type_comment -
type_comment— это необязательная строка с аннотацией типа в виде комментария.
>>> print(ast.dump(ast.parse(""" ... for x in y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ For( target=Name(id='x', ctx=Store()), iter=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[]) -
-
class ast.While(test, body, orelse) -
Цикл
while.testсодержит условие, например узелCompare.>> print(ast.dump(ast.parse(""" ... while x: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ While( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
-
class ast.Break -
class ast.Continue -
Инструкции
breakиcontinue.>>> print(ast.dump(ast.parse("""\ ... for a in b: ... if a > 5: ... break ... else: ... continue ... ... """), indent=4)) Module( body=[ For( target=Name(id='a', ctx=Store()), iter=Name(id='b', ctx=Load()), body=[ If( test=Compare( left=Name(id='a', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), body=[ Break()], orelse=[ Continue()])], orelse=[])], type_ignores=[])
-
class ast.Try(body, handlers, orelse, finalbody) -
Блоки
try. Все атрибуты содержат списки узлов для выполнения, за исключениемhandlers, который представляет собой список узловExceptHandler.>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except Exception: ... ... ... except OtherException as e: ... ... ... else: ... ... ... finally: ... ... ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))]), ExceptHandler( type=Name(id='OtherException', ctx=Load()), name='e', body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[ Expr( value=Constant(value=Ellipsis))], finalbody=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
-
class ast.TryStar(body, handlers, orelse, finalbody) -
Блоки
try, за которыми следуют частиexcept*. Атрибуты совпадают с атрибутамиTry, но узлыExceptHandlerвhandlersинтерпретируются как блокиexcept*, а не какexcept.>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except* Exception: ... ... ... """), indent=4)) Module( body=[ TryStar( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[], finalbody=[])], type_ignores=[])Добавлено в версии 3.11.
-
class ast.ExceptHandler(type, name, body) -
Одна часть
except.type— тип исключения, которому она соответствует; обычно это узелName(илиNoneдля частиexcept:, перехватывающей все исключения).name— исходная строка с именем, которому будет присвоено исключение, либоNone, если в этой части отсутствуетas foo.body— список узлов.>>> print(ast.dump(ast.parse("""\ ... try: ... a + 1 ... except TypeError: ... pass ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=BinOp( left=Name(id='a', ctx=Load()), op=Add(), right=Constant(value=1)))], handlers=[ ExceptHandler( type=Name(id='TypeError', ctx=Load()), body=[ Pass()])], orelse=[], finalbody=[])], type_ignores=[])
-
class ast.With(items, body, type_comment) -
Блок
with.items— список узловwithitem, представляющих менеджеры контекста, аbody— блок с отступом внутри контекста.-
type_comment -
type_comment— это необязательная строка с аннотацией типа в виде комментария.
-
-
class ast.withitem(context_expr, optional_vars) -
Один менеджер контекста в блоке
with.context_expr— менеджер контекста, часто представленный узломCall.optional_vars— этоName,TupleилиListдля частиas fooлибоNone, если она не используется.>>> print(ast.dump(ast.parse("""\ ... with a as b, c as d: ... something(b, d) ... """), indent=4)) Module( body=[ With( items=[ withitem( context_expr=Name(id='a', ctx=Load()), optional_vars=Name(id='b', ctx=Store())), withitem( context_expr=Name(id='c', ctx=Load()), optional_vars=Name(id='d', ctx=Store()))], body=[ Expr( value=Call( func=Name(id='something', ctx=Load()), args=[ Name(id='b', ctx=Load()), Name(id='d', ctx=Load())], keywords=[]))])], type_ignores=[])
Сопоставление с образцом
-
class ast.Match(subject, cases) -
Инструкция
match.subjectсодержит объект, проверяемый на соответствие (объект, который сопоставляется с вариантами), аcases— итерируемый объект с узламиmatch_caseдля разных вариантов.Добавлено в версии 3.10.
-
class ast.match_case(pattern, guard, body) -
Один вариант с образцом в инструкции
match.patternсодержит образец, с которым сопоставляется проверяемый объект. Обратите внимание: узлыAST, создаваемые для образцов, отличаются от узлов для выражений, даже если синтаксис у них одинаковый.Атрибут
guardсодержит выражение, которое вычисляется, если образец соответствует проверяемому объекту.bodyсодержит список узлов для выполнения, если образец соответствует объекту, а результат вычисления выражения-ограничения истинен.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] if x>0: ... ... ... case tuple(): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), guard=Compare( left=Name(id='x', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=0)]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='tuple', ctx=Load()), patterns=[], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchValue(value) -
Образец-литерал или образец-значение, сравниваемый на равенство.
value— узел выражения. Допустимые узлы-значения ограничены так, как описано в документации по инструкции сопоставления с образцом. Этот образец успешен, если проверяемый объект равен вычисленному значению.>>> print(ast.dump(ast.parse(""" ... match x: ... case "Relevant": ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchValue( value=Constant(value='Relevant')), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchSingleton(value) -
Образец-литерал, проверяющий идентичность.
value— одиночный объект, с которым выполняется сравнение:None,TrueилиFalse. Этот образец успешен, если проверяемый объект является указанной константой.>>> print(ast.dump(ast.parse(""" ... match x: ... case None: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSingleton(value=None), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchSequence(patterns) -
Образец-последовательность.
patternsсодержит образцы, с которыми сопоставляются элементы проверяемого объекта, если он является последовательностью. Совпадает с последовательностью переменной длины, если один из вложенных образцов — узелMatchStar; в противном случае совпадает с последовательностью фиксированной длины.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchStar(name) -
Сопоставляет оставшуюся часть последовательности в образце-последовательности переменной длины. Если
nameне равенNone, список оставшихся элементов последовательности связывается с этим именем, если образец-последовательность в целом совпал.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2, *rest]: ... ... ... case [*_]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2)), MatchStar(name='rest')]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchSequence( patterns=[ MatchStar()]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchMapping(keys, patterns, rest) -
Образец-отображение.
keys— последовательность узлов выражений.patterns— соответствующая последовательность узлов образцов.rest— необязательное имя, которое можно указать для захвата оставшихся элементов отображения. Допустимые выражения ключей ограничены так, как описано в документации по инструкции сопоставления с образцом.Этот образец успешен, если проверяемый объект является отображением, все вычисленные выражения ключей присутствуют в отображении, а значение, соответствующее каждому ключу, совпадает с соответствующим вложенным образцом. Если
restне равенNone, словарь с оставшимися элементами отображения связывается с этим именем, если образец-отображение в целом совпал.>>> print(ast.dump(ast.parse(""" ... match x: ... case {1: _, 2: _}: ... ... ... case {**rest}: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchMapping( keys=[ Constant(value=1), Constant(value=2)], patterns=[ MatchAs(), MatchAs()]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchMapping(keys=[], patterns=[], rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchClass(cls, patterns, kwd_attrs, kwd_patterns) -
Образец-класс.
cls— выражение, указывающее класс, с которым выполняется сопоставление.patterns— последовательность узлов образцов для сопоставления с последовательностью атрибутов сопоставления с образцом, определённой классом.kwd_attrs— последовательность дополнительных атрибутов для сопоставления (указанных в образце класса как именованные аргументы),kwd_patterns— соответствующие образцы (указанные в образце класса как значения именованных аргументов).Этот образец успешен, если проверяемый объект является экземпляром указанного класса, все позиционные образцы совпадают с соответствующими атрибутами, определёнными классом, а все указанные именованные атрибуты совпадают со своими образцами.
Примечание: классы могут определить свойство, возвращающее self, чтобы сопоставить узел образца с проверяемым экземпляром. Таким же образом сопоставляются и некоторые встроенные типы, как описано в документации по инструкции сопоставления с образцом.
>>> print(ast.dump(ast.parse(""" ... match x: ... case Point2D(0, 0): ... ... ... case Point3D(x=0, y=0, z=0): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchClass( cls=Name(id='Point2D', ctx=Load()), patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='Point3D', ctx=Load()), patterns=[], kwd_attrs=[ 'x', 'y', 'z'], kwd_patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchAs(pattern, name) -
Образец с конструкцией «as», образец захвата или образец-шаблон.
patternсодержит образец, с которым сопоставляется проверяемый объект. Если образец —None, узел представляет образец захвата (то есть отдельное имя) и всегда будет успешным.Атрибут
nameсодержит имя, с которым будет связано значение при успешном сопоставлении. ЕслиnameравенNone,patternтакже должен быть равенNone, и узел представляет образец-шаблон.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] as y: ... ... ... case _: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchAs( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), name='y'), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchAs(), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
-
class ast.MatchOr(patterns) -
Образец с конструкцией «или». Он по очереди сопоставляет каждый вложенный образец с проверяемым объектом, пока один из них не совпадёт. В этом случае образец с конструкцией «или» считается успешным. Если ни один из вложенных образцов не совпал, образец с конструкцией «или» завершается неудачей. Атрибут
patternsсодержит список узлов образцов, которые будут сопоставляться с проверяемым объектом.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] | (y): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchOr( patterns=[ MatchSequence( patterns=[ MatchAs(name='x')]), MatchAs(name='y')]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])Добавлено в версии 3.10.
Параметры типа
Параметры типа могут использоваться в классах, функциях и псевдонимах типов.
-
class ast.TypeVar(name, bound) -
typing.TypeVar.name— имя переменной типа.bound— ограничение или ограничения, если они есть. Еслиbound— этоTuple, он представляет ограничения; в противном случае он представляет ограничение.>>> print(ast.dump(ast.parse("type Alias[T: int] = list[T]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ TypeVar( name='T', bound=Name(id='int', ctx=Load()))], value=Subscript( value=Name(id='list', ctx=Load()), slice=Name(id='T', ctx=Load()), ctx=Load()))], type_ignores=[])Добавлено в версии 3.12.
-
class ast.ParamSpec(name) -
typing.ParamSpec.name— имя спецификации параметров.>>> print(ast.dump(ast.parse("type Alias[**P] = Callable[P, int]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ ParamSpec(name='P')], value=Subscript( value=Name(id='Callable', ctx=Load()), slice=Tuple( elts=[ Name(id='P', ctx=Load()), Name(id='int', ctx=Load())], ctx=Load()), ctx=Load()))], type_ignores=[])Добавлено в версии 3.12.
-
class ast.TypeVarTuple(name) -
typing.TypeVarTuple.name— имя кортежа переменных типа.>>> print(ast.dump(ast.parse("type Alias[*Ts] = tuple[*Ts]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ TypeVarTuple(name='Ts')], value=Subscript( value=Name(id='tuple', ctx=Load()), slice=Tuple( elts=[ Starred( value=Name(id='Ts', ctx=Load()), ctx=Load())], ctx=Load()), ctx=Load()))], type_ignores=[])Добавлено в версии 3.12.
Определения функций и классов
-
class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) -
Определение функции.
-
name— исходная строка с именем функции. -
args— узелarguments. -
body— список узлов внутри функции. -
decorator_list— список применяемых декораторов, упорядоченных от внешнего к внутреннему (то есть первый в списке будет применён последним). -
returns— аннотация возвращаемого значения. -
type_params— список параметров типа.
-
type_comment -
type_comment— это необязательная строка с аннотацией типа в виде комментария.
Изменено в версии 3.12: Добавлен
type_params. -
-
class ast.Lambda(args, body) -
lambda— это минимальное определение функции, которое можно использовать внутри выражения. В отличие отFunctionDef,bodyсодержит один узел.>>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4)) Module( body=[ Expr( value=Lambda( args=arguments( posonlyargs=[], args=[ arg(arg='x'), arg(arg='y')], kwonlyargs=[], kw_defaults=[], defaults=[]), body=Constant(value=Ellipsis)))], type_ignores=[])
-
class ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults) -
Аргументы функции.
-
posonlyargs,argsиkwonlyargs— списки узловarg. -
varargиkwarg— отдельные узлыarg, соответствующие параметрам*args, **kwargs. -
kw_defaults— список значений по умолчанию для аргументов, доступных только по имени. Если значение равноNone, соответствующий аргумент является обязательным. -
defaults— список значений по умолчанию для аргументов, которые можно передавать позиционно. Если значений по умолчанию меньше, они соответствуют последним n аргументам.
-
-
class ast.arg(arg, annotation, type_comment) -
Один аргумент в списке.
arg— исходная строка с именем аргумента;annotation— его аннотация, например узелName.-
type_comment -
type_comment— это необязательная строка с аннотацией типа в виде комментария
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... def f(a: 'annotation', b=1, c=2, *d, e, f=3, **g) -> 'return annotation': ... pass ... """), indent=4)) Module( body=[ FunctionDef( name='f', args=arguments( posonlyargs=[], args=[ arg( arg='a', annotation=Constant(value='annotation')), arg(arg='b'), arg(arg='c')], vararg=arg(arg='d'), kwonlyargs=[ arg(arg='e'), arg(arg='f')], kw_defaults=[ None, Constant(value=3)], kwarg=arg(arg='g'), defaults=[ Constant(value=1), Constant(value=2)]), body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], returns=Constant(value='return annotation'), type_params=[])], type_ignores=[]) -
-
class ast.Return(value) -
Инструкция
return.>>> print(ast.dump(ast.parse('return 4'), indent=4)) Module( body=[ Return( value=Constant(value=4))], type_ignores=[])
-
class ast.Yield(value) -
class ast.YieldFrom(value) -
Выражение
yieldилиyield from. Поскольку это выражения, их необходимо заключать в узелExpr, если возвращаемое значение не используется.>>> print(ast.dump(ast.parse('yield x'), indent=4)) Module( body=[ Expr( value=Yield( value=Name(id='x', ctx=Load())))], type_ignores=[]) >>> print(ast.dump(ast.parse('yield from x'), indent=4)) Module( body=[ Expr( value=YieldFrom( value=Name(id='x', ctx=Load())))], type_ignores=[])
-
class ast.Global(names) -
class ast.Nonlocal(names) -
Инструкции
globalиnonlocal.names— список исходных строк.>>> print(ast.dump(ast.parse('global x,y,z'), indent=4)) Module( body=[ Global( names=[ 'x', 'y', 'z'])], type_ignores=[]) >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) Module( body=[ Nonlocal( names=[ 'x', 'y', 'z'])], type_ignores=[])
-
class ast.ClassDef(name, bases, keywords, body, decorator_list, type_params) -
Определение класса.
-
name— исходная строка с именем класса -
bases— список узлов явно указанных базовых классов. -
keywords— список узловkeyword, главным образом для «метакласса». Другие ключевые слова будут переданы метаклассу согласно PEP 3115. -
body— список узлов, представляющих код внутри определения класса. -
decorator_list— список узлов, как и вFunctionDef. -
type_params— список параметров типа.
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... class Foo(base1, base2, metaclass=meta): ... pass ... """), indent=4)) Module( body=[ ClassDef( name='Foo', bases=[ Name(id='base1', ctx=Load()), Name(id='base2', ctx=Load())], keywords=[ keyword( arg='metaclass', value=Name(id='meta', ctx=Load()))], body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], type_params=[])], type_ignores=[])Изменено в версии 3.12: Добавлен
type_params. -
Асинхронные операции и await
-
class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) -
Определение
async defфункции. Содержит те же поля, что иFunctionDef.Изменено в версии 3.12: Добавлен
type_params.
-
class ast.Await(value) -
Выражение
await.value— это объект, ожидания завершения которого оно ожидает. Допустимо только внутри телаAsyncFunctionDef.
>>> print(ast.dump(ast.parse("""\
... async def f():
... await other_func()
... """), indent=4))
Module(
body=[
AsyncFunctionDef(
name='f',
args=arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()),
args=[],
keywords=[])))],
decorator_list=[],
type_params=[])],
type_ignores=[])
-
class ast.AsyncFor(target, iter, body, orelse, type_comment) -
class ast.AsyncWith(items, body, type_comment) -
Циклы
async forи менеджеры контекстаasync with. У них те же поля, что и уForиWithсоответственно. Допустимы только внутри телаAsyncFunctionDef.
Примечание
При разборе строки с помощью ast.parse() узлы операторов (подклассы ast.operator, ast.unaryop, ast.cmpop, ast.boolop и ast.expr_context) в возвращённом дереве будут одиночными экземплярами. Изменения одного такого узла отразятся на всех остальных вхождениях того же значения (например, ast.Add).
Вспомогательные средства ast
Помимо классов узлов, модуль ast определяет следующие вспомогательные функции и классы для обхода абстрактных синтаксических деревьев:
-
ast.parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None) -
Разбирает исходный код и создает узел AST. Эквивалентно
compile(source, filename, mode, ast.PyCF_ONLY_AST).Если задан параметр
type_comments=True, синтаксический анализатор изменяется так, чтобы проверять комментарии типов и возвращать их, как указано в PEP 484 и PEP 526. Это эквивалентно добавлениюast.PyCF_TYPE_COMMENTSк флагам, переданным вcompile(). При этом будут сообщаться синтаксические ошибки, если комментарии типов расположены неверно. Без этого флага комментарии типов будут игнорироваться, а полеtype_commentу выбранных узлов AST всегда будет иметь значениеNone. Кроме того, расположение комментариев# type: ignoreбудет возвращаться в атрибутеtype_ignoresобъектаModule(в противном случае это всегда пустой список).Кроме того, если
modeимеет значение'func_type', синтаксис входных данных изменяется в соответствии с «комментариями типов сигнатур» из PEP 484, например(str, int) -> List[str].Если задать для
feature_versionкортеж(major, minor), будет предпринята «наилучшая из возможных» попытка разбора с использованием грамматики этой версии Python. Например, при заданииfeature_version=(3, 9)будет предпринята попытка запретить разбор операторовmatch. В настоящее времяmajorдолжно быть равно3. Самая ранняя поддерживаемая версия —(3, 4)(в будущих версиях Python она может стать более поздней); самая поздняя —sys.version_info[0:2]. «Наилучшая из возможных» попытка означает, что нет гарантии, что результат разбора (или успешность разбора) будет таким же, как при запуске в версии Python, соответствующейfeature_version.Если исходный код содержит нулевой символ (
\0), возникает исключениеValueError.Предупреждение
Обратите внимание: успешный разбор исходного кода в объект AST не гарантирует, что переданный исходный код является допустимым кодом Python, который можно выполнить, поскольку на этапе компиляции могут возникнуть дополнительные исключения
SyntaxError. Например, исходный кодreturn 42создает допустимый узел AST для оператора return, но его нельзя скомпилировать отдельно (он должен находиться внутри узла функции).В частности,
ast.parse()не выполняет проверку областей видимости, которую выполняет этап компиляции.Предупреждение
Из-за ограничений глубины стека в компиляторе AST Python интерпретатор Python может аварийно завершиться при разборе достаточно длинной или сложной строки.
Изменено в версии 3.8: Добавлены
type_comments,mode='func_type'иfeature_version.
-
ast.unparse(ast_obj) -
Преобразует объект
ast.ASTв исходный код и возвращает строку с кодом, который при повторном разборе с помощьюast.parse()создал бы эквивалентный объектast.AST.Предупреждение
Полученная строка кода не обязательно будет совпадать с исходным кодом, на основе которого был создан объект
ast.AST(с учетом оптимизаций компилятора, таких как кортежи и неизменяемые множества-константы).Предупреждение
Попытка преобразовать в исходный код очень сложное выражение приведет к исключению
RecursionError.Добавлено в версии 3.9.
-
ast.literal_eval(node_or_string) -
Вычисляет узел выражения или строку, содержащую только литерал Python либо отображение контейнера. Переданная строка или узел могут состоять только из следующих литеральных структур Python: строк, байтовых строк, чисел, кортежей, списков, словарей, множеств, логических значений,
NoneиEllipsis.Эту функцию можно использовать для вычисления строк, содержащих значения Python, без необходимости самостоятельно разбирать эти значения. Она не предназначена для вычисления произвольных сложных выражений, например выражений с операторами или индексацией.
Ранее эта функция описывалась как «безопасная», но не уточнялось, что это означает. Это вводило в заблуждение. В отличие от более универсальной функции
eval(), она специально предназначена для выполнения без запуска кода Python. Здесь нет пространства имен, поиска имен или возможности вызывать внешние объекты. Однако функция не защищена от атак: относительно небольшие входные данные могут привести к исчерпанию памяти или стека C и аварийному завершению процесса. Некоторые входные данные также могут привести к чрезмерному использованию процессора и отказу в обслуживании. Поэтому не рекомендуется вызывать эту функцию для недоверенных данных.Предупреждение
Из-за ограничений глубины стека в компиляторе AST Python интерпретатор Python может аварийно завершиться.
В зависимости от некорректных входных данных могут возникнуть исключения
ValueError,TypeError,SyntaxError,MemoryErrorиRecursionError.Изменено в версии 3.2: Теперь поддерживаются байтовые строки и литералы множеств.
Изменено в версии 3.9: Теперь поддерживается создание пустых множеств с помощью
'set()'.Изменено в версии 3.10: Для строковых входных данных теперь удаляются начальные пробелы и символы табуляции.
-
ast.get_docstring(node, clean=True) -
Возвращает строку документации заданного узла (который должен быть узлом
FunctionDef,AsyncFunctionDef,ClassDefилиModule) либоNone, если строки документации нет. Если clean имеет значение true, отступы в строке документации приводятся в порядок с помощьюinspect.cleandoc().Изменено в версии 3.5: Теперь поддерживается
AsyncFunctionDef.
-
ast.get_source_segment(source, node, *, padded=False) -
Возвращает фрагмент исходного кода из source, который создал node. Если отсутствует какая-либо информация о расположении (
lineno,end_lineno,col_offsetилиend_col_offset), возвращаетсяNone.Если padded имеет значение
True, первая строка многострочного оператора дополняется пробелами, чтобы соответствовать исходному расположению.Добавлено в версии 3.8.
-
ast.fix_missing_locations(node) -
При компиляции дерева узлов с помощью
compile()компилятор ожидает атрибутыlinenoиcol_offsetу каждого узла, который их поддерживает. Заполнять эти атрибуты для созданных узлов довольно утомительно, поэтому эта вспомогательная функция рекурсивно добавляет отсутствующие атрибуты, присваивая им значения родительского узла. Рекурсивная обработка начинается с node.
-
ast.increment_lineno(node, n=1) -
Увеличивает номер начальной и конечной строки каждого узла дерева, начиная с node, на n. Это полезно, чтобы «переместить код» в другое место файла.
-
ast.copy_location(new_node, old_node) -
По возможности копирует расположение в исходном коде (
lineno,col_offset,end_linenoиend_col_offset) из old_node в new_node и возвращает new_node.
-
ast.iter_fields(node) -
Для каждого поля из
node._fields, присутствующего в node, выдает кортеж(fieldname, value).
-
ast.iter_child_nodes(node) -
Выдает все непосредственные дочерние узлы node, то есть все поля, содержащие узлы, и все элементы полей, представляющих собой списки узлов.
-
ast.walk(node) -
Рекурсивно выдает все узлы-потомки дерева, начиная с node (включая сам node), в произвольном порядке. Это полезно, если требуется изменять узлы на месте и контекст не имеет значения.
-
class ast.NodeVisitor -
Базовый класс посетителя узлов, который обходит абстрактное синтаксическое дерево и вызывает функцию-посетитель для каждого найденного узла. Эта функция может возвращать значение, которое передается методом
visit().Этот класс предназначен для создания подклассов, в которых добавляются методы-посетители.
-
visit(node) -
Посещает узел. Реализация по умолчанию вызывает метод с именем
self.visit_classname, где classname — имя класса узла, илиgeneric_visit(), если такого метода нет.
-
generic_visit(node) -
Этот посетитель вызывает
visit()для всех дочерних узлов.Обратите внимание: дочерние узлы узлов, для которых определен собственный метод-посетитель, не будут посещены, если посетитель не вызовет
generic_visit()или не посетит их самостоятельно.
-
visit_Constant(node) -
Обрабатывает все узлы-константы.
Не используйте
NodeVisitor, если хотите изменять узлы во время обхода. Для этого существует специальный посетитель (NodeTransformer), позволяющий вносить изменения.Устарело с версии 3.8: Методы
visit_Num(),visit_Str(),visit_Bytes(),visit_NameConstant()иvisit_Ellipsis()теперь устарели и не будут вызываться в будущих версиях Python. Добавьте методvisit_Constant(), чтобы обрабатывать все узлы-константы. -
-
class ast.NodeTransformer -
Подкласс
NodeVisitor, который обходит абстрактное синтаксическое дерево и позволяет изменять узлы.NodeTransformerобходит AST и использует возвращаемые методы-посетители значения для замены или удаления старого узла. Если метод-посетитель возвращаетNone, узел удаляется из своего расположения; в противном случае он заменяется возвращенным значением. Возвращенным значением может быть исходный узел — тогда замена не происходит.Ниже приведен пример преобразователя, который заменяет все вхождения поиска имен (
foo) наdata['foo']:class RewriteName(NodeTransformer): def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), slice=Constant(value=node.id), ctx=node.ctx )Помните: если у обрабатываемого узла есть дочерние узлы, необходимо либо самостоятельно преобразовать дочерние узлы, либо сначала вызвать для этого узла метод
generic_visit().Для узлов, входивших в коллекцию операторов (это относится ко всем узлам операторов), посетитель может возвращать список узлов вместо одного узла.
Если
NodeTransformerдобавляет новые узлы (которых не было в исходном дереве) без указания информации об их расположении (например,lineno), для пересчета информации о расположении следует вызватьfix_missing_locations()для нового поддерева:tree = ast.parse('foo', mode='eval') new_tree = fix_missing_locations(RewriteName().visit(tree))Обычно преобразователь используется следующим образом:
node = YourTransformer().visit(node)
-
ast.dump(node, annotate_fields=True, include_attributes=False, *, indent=None) -
Возвращает форматированный дамп дерева, содержащегося в node. Это в основном полезно для отладки. Если annotate_fields имеет значение true (по умолчанию), в возвращаемой строке будут показаны имена полей и их значения. Если annotate_fields имеет значение false, строка результата будет компактнее: однозначно определяемые имена полей будут опущены. По умолчанию такие атрибуты, как номера строк и смещения столбцов, не включаются в дамп. Чтобы включить их, параметру include_attributes можно присвоить значение true.
Если indent — неотрицательное целое число или строка, дерево будет красиво отформатировано с заданным уровнем отступа. Уровень отступа 0, отрицательное значение или
""добавит только символы перевода строки.None(значение по умолчанию) задает представление в одну строку. Положительное целое число в качестве уровня отступа задает количество пробелов на каждом уровне. Если indent — строка (например,"\t"), для отступов каждого уровня будет использоваться эта строка.Изменено в версии 3.9: Добавлен параметр indent.
Флаги компилятора
Чтобы изменить поведение при компиляции программы, функции compile() можно передать следующие флаги:
-
ast.PyCF_ALLOW_TOP_LEVEL_AWAIT -
Включает поддержку
await,async for,async withверхнего уровня и асинхронных включений.Добавлено в версии 3.8.
-
ast.PyCF_ONLY_AST -
Создает и возвращает абстрактное синтаксическое дерево вместо скомпилированного объекта кода.
Использование командной строки
Добавлено в версии 3.9.
Модуль ast можно запускать из командной строки как скрипт. Это делается так:
python -m ast [-m <mode>] [-a] [infile]
Поддерживаются следующие параметры:
-
-h, --help -
Показать справку и завершить работу.
-
-m <mode> -
--mode <mode> -
Указывает, какой вид кода необходимо скомпилировать, как и аргумент mode функции
parse().
-
--no-type-comments -
Не разбирать комментарии типов.
-
-a, --include-attributes -
Включить такие атрибуты, как номера строк и смещения столбцов.
-
-i <indent> -
--indent <indent> -
Отступы узлов AST (количество пробелов).
Если указан параметр infile, его содержимое разбирается в AST и выводится в stdout. В противном случае содержимое считывается из stdin.
См. также
Green Tree Snakes — внешний ресурс документации с подробной информацией о работе с AST Python.
ASTTokens добавляет в AST Python сведения о расположении токенов и текста в исходном коде, из которого они были созданы. Это полезно для инструментов преобразования исходного кода.
leoAst.py объединяет представления программ Python на основе токенов и деревьев разбора, добавляя двусторонние ссылки между токенами и узлами AST.
LibCST разбирает код в конкретное синтаксическое дерево, которое напоминает дерево AST и сохраняет все детали форматирования. Оно полезно для создания приложений автоматического рефакторинга (codemod) и линтеров.
Parso — синтаксический анализатор Python, поддерживающий восстановление после ошибок и разбор с возможностью обратного преобразования для разных версий Python (в нескольких версиях Python). Parso также может перечислять несколько синтаксических ошибок в файле Python.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/ast.html