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, expr? default_value)
| ParamSpec(identifier name, expr? default_value)
| TypeVarTuple(identifier name, expr? default_value)
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
}
Классы узлов¶
- class ast.AST¶
Это основа всех классов узлов AST. Собственно классы узлов являются производными от файла
Parser/Python.asdl
, который воспроизводится above. Они определены в_ast
C-модуле и реэкспортируются вast
.Для каждого символа левой стороны в абстрактной грамматике (например,
ast.stmt
илиast.expr
) определен один класс. Кроме того, для каждого конструктора правой стороны определен один класс; эти классы наследуются от классов для деревьев левой стороны. Например,ast.BinOp
наследуется отast.expr
. Для правил производства с альтернативами (они же «суммы») класс левой стороны является абстрактным: создаются только экземпляры конкретных узлов конструктора.- _fields¶
Каждый конкретный класс имеет атрибут
_fields
, который задает имена всех дочерних узлов.Каждый экземпляр конкретного класса имеет по одному атрибуту для каждого дочернего узла, тип которого определен в грамматике. Например, у экземпляров
ast.BinOp
есть атрибутleft
типаast.expr
.Если эти атрибуты отмечены в грамматике как необязательные (с помощью вопросительного знака), то значение может быть
None
. Если атрибуты могут иметь ноль или более значений (отмечены звездочкой), то значения представляются в виде списков Python. При компиляции AST сcompile()
все возможные атрибуты должны присутствовать и иметь допустимые значения.
- _field_types¶
Атрибут
_field_types
каждого конкретного класса представляет собой словарь, отображающий имена полей (также перечисленных в_fields
) на их типы.>>> ast.TypeVar._field_types {'name': <class 'str'>, 'bound': ast.expr | None, 'default_value': ast.expr | None}
Added in version 3.13.
- 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(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0)
Если поле, которое в грамматике является необязательным, опущено в конструкторе, то по умолчанию оно принимает значение
None
. Если опущено поле со списком, то по умолчанию используется пустой список. Если опущено поле типаast.expr_context
, то по умолчанию оно принимает значениеLoad()
. Если опущено любое другое поле, возникает ошибкаDeprecationWarning
, и узел AST не будет содержать этого поля. В Python 3.15 это условие приведет к ошибке.
Изменено в версии 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. Пока же их инстанцирование вернет экземпляр другого класса.
Утратил актуальность с версии 3.13, будет удален в версии 3.15: Предыдущие версии Python позволяли создавать узлы AST, в которых отсутствовали необходимые поля. Аналогично, конструкторы узлов AST позволяли использовать произвольные аргументы ключевых слов, которые устанавливались в качестве атрибутов узла AST, даже если они не соответствовали ни одному из полей узла AST. Это поведение устарело и будет удалено в Python 3.15.
Примечание
Описания конкретных классов узлов, представленные здесь, были первоначально адаптированы из фантастического проекта Green Tree Snakes и всех его участников.
Корневые узлы¶
- class ast.Module(body, type_ignores)¶
Модуль Python, как и file input. Тип узла, генерируемый
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))])
- class ast.Expression(body)¶
Одиночный узел Python expression input. Тип узла, генерируемый
ast.parse()
, когда режим равен"eval"
.body - это единственный узел, один из expression types.
>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
- class ast.Interactive(body)¶
Одиночный interactive input, как в Интерактивный режим. Тип узла, генерируемый
ast.parse()
, когда режим равен"single"
.тело - это
list
из statement nodes.>>> 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()
, когда режим равен"func_type"
.Комментарии такого типа будут выглядеть следующим образом:
def sum_two_number(a, b): # type: (int, int) -> int return a + b
argtypes - это
list
из expression nodes.Возвращается один expression node.
>>> 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()))
Added in version 3.8.
Литература¶
- class ast.Constant(value)¶
Постоянное значение. Атрибут
value
литералаConstant
содержит объект Python, который он представляет. Представленные значения могут быть простыми типами, такими как число, строка илиNone
, а также неизменяемыми контейнерными типами (кортежи и фростенсеты), если все их элементы являются константными.>>> 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:
!a
форматирование ascii
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())]), 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
, аNone
- на соответствующей позиции вkeys
.>>> 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()))]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])])
- 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()))])
Выражения¶
- 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())))])
- 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.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
, представляющих аргументы, передаваемые по ключевому слову.
Аргументы
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)))
Added in version 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()), 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()), 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()), 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())]), generators=[ comprehension( target=Name(id='line', ctx=Store()), iter=Name(id='file', ctx=Load()), is_async=0), comprehension( target=Name(id='c', ctx=Store()), iter=Name(id='line', ctx=Load()), 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()), 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))]) >>> 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()))])
- class ast.AnnAssign(target, annotation, value, simple)¶
Назначение с аннотацией типа.
target
- это отдельный узел, который может бытьName
,Attribute
илиSubscript
.annotation
- это аннотация, например узелConstant
илиName
.value
- один необязательный узел.simple
- булево целое число, установленное в True для узлаName
вtarget
, которые не появляются между скобками и, следовательно, являются чистыми именами, а не выражениями.>>> 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)]) >>> 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)]) >>> 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)]) >>> 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)])
- 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))])
- 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()))])
- 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()))])
- 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())])])
- class ast.Pass¶
Высказывание
pass
.>>> print(ast.dump(ast.parse('pass'), indent=4)) Module( body=[ Pass()])
- class ast.TypeAlias(name, type_params, value)¶
Псевдоним type alias, созданный с помощью оператора
type
.name
- это имя псевдонима,type_params
- список type parameters, аvalue
- значение псевдонима типа.>>> print(ast.dump(ast.parse('type Alias = int'), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), value=Name(id='int', ctx=Load()))])
Added in version 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')])])
- 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)])
- 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)])
Поток управления¶
Примечание
Необязательные предложения, такие как 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))])])])
- 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))])])
- 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))])])
- 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()])])])
- 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))])])
- 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))])])])
Added in version 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()])])])
- 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())]))])])
Соответствие образцу¶
- class ast.Match(subject, cases)¶
Утверждение
match
subject
содержит субъект соответствия (объект, который сопоставляется со случаями), аcases
содержит итерациюmatch_case
узлов с различными случаями.Added in version 3.10.
- class ast.match_case(pattern, guard, body)¶
Одиночный шаблон случая в операторе
match
.pattern
содержит шаблон соответствия, с которым будет сопоставлен объект. Обратите внимание, что узлыAST
, создаваемые для шаблонов, отличаются от узлов, создаваемых для выражений, даже если у них одинаковый синтаксис.Атрибут
guard
содержит выражение, которое будет вычислено, если шаблон совпадет с объектом.body
содержит список узлов, которые будут выполняться, если шаблон совпадает и результат оценки защитного выражения равен true.>>> 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())), body=[ Expr( value=Constant(value=Ellipsis))])])])
Added in version 3.10.
- class ast.MatchValue(value)¶
Литерал соответствия или шаблон значения, который сравнивает по равенству.
value
- это узел выражения. Допустимые узлы значений ограничены, как описано в документации по оператору match. Этот шаблон успешен, если объект совпадения равен оцениваемому значению.>>> 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))])])])
Added in version 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))])])])
Added in version 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))])])])
Added in version 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))])])])
Added in version 3.10.
- class ast.MatchMapping(keys, patterns, rest)¶
Шаблон сопоставления.
keys
- последовательность узлов выражения.patterns
- соответствующая последовательность узлов шаблона.rest
- необязательное имя, которое может быть указано для захвата оставшихся элементов отображения. Допустимые ключевые выражения ограничены, как описано в документации по оператору соответствия.Этот шаблон успешен, если объект является отображением, все оцененные ключевые выражения присутствуют в отображении, а значение, соответствующее каждому ключу, совпадает с соответствующим подшаблоном. Если
rest
не являетсяNone
, то в случае успеха шаблона отображения к этому имени привязывается dict, содержащий остальные элементы отображения.>>> 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(rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])])
Added in version 3.10.
- class ast.MatchClass(cls, patterns, kwd_attrs, kwd_patterns)¶
Шаблон класса соответствия.
cls
- выражение, задающее номинальный класс для сопоставления.patterns
- последовательность узлов шаблона для сопоставления с определенной классом последовательностью атрибутов сопоставления.kwd_attrs
- последовательность дополнительных атрибутов для сопоставления (указываются как аргументы ключевых слов в шаблоне класса),kwd_patterns
- соответствующие шаблоны (указываются как значения ключевых слов в шаблоне класса).Этот шаблон работает, если субъект является экземпляром указанного класса, все позиционные шаблоны совпадают с соответствующими атрибутами, определенными классом, а все указанные ключевые слова-атрибуты совпадают с соответствующим шаблоном.
Примечание: классы могут определять свойство, возвращающее self, для сопоставления узла шаблона с сопоставляемым экземпляром. Некоторые встроенные типы также сопоставляются таким образом, как описано в документации по оператору match.
>>> 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))]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='Point3D', ctx=Load()), 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))])])])
Added in version 3.10.
- class ast.MatchAs(pattern, name)¶
Совпадение «как шаблон», шаблон захвата или шаблон подстановочного знака.
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))])])])
Added in version 3.10.
- class ast.MatchOr(patterns)¶
Соответствие «или-шаблон». Шаблон «или» поочередно сопоставляет с объектом каждый из своих подшаблонов, пока один из них не будет успешным. Тогда шаблон «или» считается успешным. Если ни один из подшаблонов не достиг успеха, шаблон or терпит неудачу. Атрибут
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))])])])
Added in version 3.10.
Параметры типа¶
Type parameters может существовать в классах, функциях и псевдонимах типов.
- class ast.TypeVar(name, bound, default_value)¶
A
typing.TypeVar
. name - имя переменной типа. bound - это ограничение или ограничения, если таковые имеются. Если bound - этоTuple
, то он представляет ограничения; в противном случае он представляет ограничение. default_value - значение по умолчанию; если уTypeVar
нет значения по умолчанию, этот атрибут будет установлен вNone
.>>> print(ast.dump(ast.parse("type Alias[T: int = bool] = list[T]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ TypeVar( name='T', bound=Name(id='int', ctx=Load()), default_value=Name(id='bool', ctx=Load()))], value=Subscript( value=Name(id='list', ctx=Load()), slice=Name(id='T', ctx=Load()), ctx=Load()))])
Added in version 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
- class ast.ParamSpec(name, default_value)¶
A
typing.ParamSpec
. name - имя спецификации параметра. default_value - значение по умолчанию; если уParamSpec
нет значения по умолчанию, этот атрибут будет установлен вNone
.>>> print(ast.dump(ast.parse("type Alias[**P = (int, str)] = Callable[P, int]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ ParamSpec( name='P', default_value=Tuple( elts=[ Name(id='int', ctx=Load()), Name(id='str', ctx=Load())], ctx=Load()))], 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()))])
Added in version 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
- class ast.TypeVarTuple(name, default_value)¶
A
typing.TypeVarTuple
. name - имя кортежа переменных типа. default_value - значение по умолчанию; если уTypeVarTuple
нет значения по умолчанию, этот атрибут будет установлен вNone
.>>> 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', default_value=Tuple(ctx=Load()))], value=Subscript( value=Name(id='tuple', ctx=Load()), slice=Tuple( elts=[ Starred( value=Name(id='Ts', ctx=Load()), ctx=Load())], ctx=Load()), ctx=Load()))])
Added in version 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
Определения функций и классов¶
- class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment, type_params)¶
Определение функции.
name
- необработанная строка имени функции.args
является узломarguments
.body
- список узлов внутри функции.decorator_list
- это список декораторов, которые будут применены, хранящийся крайним (т.е. первый в списке будет применен последним).returns
- это аннотация возврата.type_params
- это список type parameters.
- 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( args=[ arg(arg='x'), arg(arg='y')]), body=Constant(value=Ellipsis)))])
- 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( 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'))])
- class ast.Return(value)¶
Высказывание
return
.>>> print(ast.dump(ast.parse('return 4'), indent=4)) Module( body=[ Return( value=Constant(value=4))])
- 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())))]) >>> print(ast.dump(ast.parse('yield from x'), indent=4)) Module( body=[ Expr( value=YieldFrom( value=Name(id='x', ctx=Load())))])
- 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'])]) >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) Module( body=[ Nonlocal( names=[ 'x', 'y', 'z'])])
- class ast.ClassDef(name, bases, keywords, body, decorator_list, type_params)¶
Определение класса.
name
- необработанная строка для имени классаbases
- список узлов для явно указанных базовых классов.keywords
- это список узловkeyword
, в основном для „metaclass“. Другие ключевые слова будут переданы в метакласс в соответствии с PEP-3115.body
- это список узлов, представляющих код в определении класса.decorator_list
- это список узлов, как вFunctionDef
.type_params
- это список type parameters.
>>> 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())])])
Изменено в версии 3.12: Добавлено
type_params
.
Async и ожидание¶
- 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(),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()))))])])
- 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, optimize=-1)¶
Разбор источника на узлы AST. Эквивалентно
compile(source, filename, mode, flags=FLAGS_VALUE, optimize=optimize)
, гдеFLAGS_VALUE
- этоast.PyCF_ONLY_AST
, еслиoptimize <= 0
иast.PyCF_OPTIMIZED_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, 7)
(и она может увеличиться в будущих версиях Python); самая высокая -sys.version_info[0:2]
. Попытка «Best-effort» означает, что нет гарантии, что разбор (или успех разбора) будет таким же, как при выполнении на версии 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
.Изменено в версии 3.13: Минимальной поддерживаемой версией для
feature_version
теперь является(3, 7)
. Был добавлен аргументoptimize
.
- ast.unparse(ast_obj)¶
Разберите объект
ast.AST
и сгенерируйте строку с кодом, который произведет эквивалентный объектast.AST
, если его разобрать с помощьюast.parse()
.Предупреждение
Полученная строка кода не обязательно будет равна исходному коду, сгенерировавшему объект
ast.AST
(без каких-либо оптимизаций компилятора, таких как константные кортежи/фрозенсеты).Предупреждение
Попытка разобрать сложное выражение приведет к появлению
RecursionError
.Added in version 3.9.
- ast.literal_eval(node_or_string)¶
Оценивает узел выражения или строку, содержащую только литерал Python или контейнерное отображение. Предоставленная строка или узел могут состоять только из следующих буквенных структур Python: строк, байтов, чисел, кортежей, списков, диктов, множеств, булевых чисел,
None
иEllipsis
.Он может использоваться для оценки строк, содержащих значения Python, без необходимости самостоятельного разбора значений. Он не способен вычислять произвольно сложные выражения, например, с операторами или индексацией.
В прошлом эта функция была задокументирована как «безопасная», без определения того, что это значит. Это вводило в заблуждение. В отличие от более общей
eval()
, она специально предназначена для того, чтобы не выполнять код Python. Здесь нет ни пространства имен, ни поиска по имени, ни возможности вызова. Но он не свободен от атак: Относительно небольшой ввод может привести к исчерпанию памяти или к исчерпанию стека C, что приведет к краху процесса. Также существует возможность отказа в обслуживании при чрезмерном потреблении процессора при некоторых входных данных. Поэтому вызывать его на недоверенных данных не рекомендуется.Предупреждение
Возможно аварийное завершение работы интерпретатора Python из-за ограничений глубины стека в AST-компиляторе Python.
В зависимости от искаженного ввода он может поднять
ValueError
,TypeError
,SyntaxError
,MemoryError
иRecursionError
.Изменено в версии 3.2: Теперь можно использовать байты и литералы множеств.
Изменено в версии 3.9: Теперь поддерживается создание пустых множеств с помощью
'set()'
.Изменено в версии 3.10: При вводе строк теперь удаляются пробелы и табуляции.
- ast.get_docstring(node, clean=True)¶
Возвращает docstring данного узла (который должен быть узлом
FunctionDef
,AsyncFunctionDef
,ClassDef
илиModule
), илиNone
, если он не имеет docstring. Если clean равно true, очистите отступы в строке документа с помощьюinspect.cleandoc()
.Изменено в версии 3.5:
AsyncFunctionDef
теперь поддерживается.
- ast.get_source_segment(source, node, *, padded=False)¶
Получение сегмента исходного кода источника, породившего узел. Если некоторая информация о местоположении (
lineno
,end_lineno
,col_offset
илиend_col_offset
) отсутствует, возвращаетсяNone
.Если значение padded равно
True
, то первая строка многострочного оператора будет заполнена пробелами в соответствии с ее исходной позицией.Added in version 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
) из старого_узла в новый_узел, если это возможно, и верните новый_узел.
- ast.iter_fields(node)¶
Выдает кортеж
(fieldname, value)
для каждого поля вnode._fields
, которое присутствует на узле.
- 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, show_empty=False)¶
Возвращает форматированный дамп дерева в node. В основном это полезно для отладки. Если annotate_fields равно true (по умолчанию), то в возвращаемой строке будут указаны имена и значения полей. Если annotate_fields равно false, то результирующая строка будет более компактной за счет исключения однозначных имен полей. Такие атрибуты, как номера строк и смещения столбцов, по умолчанию не передаются в дамп. Если это необходимо, для параметра include_attributes можно установить значение true.
Если indent - неотрицательное целое число или строка, то дерево будет красиво напечатано с этим уровнем отступа. Уровень отступа 0, отрицательный или
""
будет вставлять только новые строки.None
(по умолчанию) выбирает однострочное представление. При использовании целого положительного значения отступа на каждом уровне отступается столько-то пробелов. Если indent - это строка (например,"\t"
), то эта строка используется для отступа каждого уровня.Если show_empty имеет значение
False
(по умолчанию), то пустые списки и поля, имеющие значениеNone
, будут опущены в выводе.Изменено в версии 3.9: Добавлена опция indent.
Изменено в версии 3.13: Добавлена опция show_empty.
>>> print(ast.dump(ast.parse("""\ ... async def f(): ... await other_func() ... """), indent=4, show_empty=True)) 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=[])
Флаги компилятора¶
Следующие флаги могут быть переданы в compile()
, чтобы изменить влияние на компиляцию программы:
- ast.PyCF_ALLOW_TOP_LEVEL_AWAIT¶
Включает поддержку верхнеуровневых
await
,async for
,async with
и async-компонентов.Added in version 3.8.
- ast.PyCF_ONLY_AST¶
Генерирует и возвращает абстрактное дерево синтаксиса вместо того, чтобы возвращать объект скомпилированного кода.
- ast.PyCF_OPTIMIZED_AST¶
Возвращаемый AST оптимизируется в соответствии с аргументом optimize в
compile()
илиast.parse()
.Added in version 3.13.
- ast.PyCF_TYPE_COMMENTS¶
Включает поддержку комментариев типов в стиле PEP 484 и PEP 526 (
# type: <type>
,# type: ignore <stuff>
).Added in version 3.8.
- ast.compare(a, b, /, *, compare_attributes=False)¶
Рекурсивно сравнивает два AST.
compare_attributes влияет на то, учитываются ли атрибуты AST при сравнении. Если compare_attributes равно
False
(по умолчанию), то атрибуты игнорируются. В противном случае все они должны быть равны. Эта опция полезна для проверки того, что AST структурно одинаковы, но различаются пробелами или другими подобными деталями. Атрибуты включают номера строк и смещения столбцов.Added in version 3.14.
Использование командной строки¶
Added in version 3.9.
Модуль ast
может быть выполнен как скрипт из командной строки. Это просто:
python -m ast [-m <mode>] [-a] [infile]
Принимаются следующие варианты:
- -h, --help¶
Покажите сообщение о помощи и выйдите.
- -m <mode>¶
- --mode <mode>¶
Укажите, какой тип кода должен быть скомпилирован, подобно аргументу mode в
parse()
.
- --no-type-comments¶
Не разбирайте комментарии типа.
- -a, --include-attributes¶
Включите такие атрибуты, как номера строк и смещения колонок.
Если указан infile
, его содержимое разбирается на AST и выводится в stdout. В противном случае содержимое считывается из stdin.
См.также
Green Tree Snakes, внешний ресурс документации, содержит подробную информацию о работе с Python AST.
ASTTokens аннотирует Python AST с указанием позиций лексем и текста в исходном коде, который их породил. Это полезно для инструментов, которые занимаются преобразованием исходного кода.
leoAst.py объединяет представления программ на python, основанные на лексемах и деревьях разбора, вставляя двусторонние связи между лексемами и узлами ast.
LibCST разбирает код в виде конкретного синтаксического дерева, которое выглядит как дерево ast и сохраняет все детали форматирования. Это полезно для создания приложений для автоматического рефакторинга (codemod) и линтеров.
Parso - это парсер Python, который поддерживает восстановление ошибок и парсинг в обе стороны для разных версий Python (в нескольких версиях Python). Parso также способен перечислить множество синтаксических ошибок в вашем Python-файле.