ast
— Абстрактные синтаксические деревья¶
Исходный код: Lib/ast.py
Модуль ast
помогает приложениям на Python обрабатывать деревья грамматики абстрактного синтаксиса Python. Сам абстрактный синтаксис может меняться с каждым выпуском Python; этот модуль помогает программно определить, как выглядит текущая грамматика.
Абстрактное синтаксическое дерево может быть сгенерировано путем передачи ast.PyCF_ONLY_AST
в качестве флага встроенной функции compile()
или с помощью вспомогательного средства parse()
, предоставляемого в этом модуле. Результатом будет дерево объектов, все классы которых наследуются от ast.AST
. Абстрактное синтаксическое дерево может быть скомпилировано в объект кода Python с помощью встроенной функции compile()
.
Абстрактная грамматика¶
Абстрактная грамматика в настоящее время определяется следующим образом:
Классы узлов¶
- 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()
.
- 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. Тем временем при их создании будет возвращен экземпляр другого класса.
Примечание
Описания конкретных классов узлов, представленные здесь, изначально были адаптированы из проекта fantastic Green Tree Snakes и всех его участников.
Корневые узлы¶
- class ast.Module(body, type_ignores)¶
Модуль Python, как и в случае с file input. Тип узла, сгенерированный
ast.parse()
в режиме"exec"
по умолчанию*.тело - это
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 expression input. Тип узла генерируется с помощью
ast.parse()
, когда mode равен"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()
, когда mode равен"single"
.body - это
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)¶
Представление типа comments старого образца для функций, поскольку версии Python до 3.5 не поддерживали аннотации PEP 484. Тип узла генерируется с помощью
ast.parse()
, когда mode равен"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()))
Добавлено в версии 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())], 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
, с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()))], 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
содержит один из других узлов в этом разделе, aConstant
, aName
,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.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
- это узел, обычно aName
.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-узел создается оператором присваивания выражений (также известным как оператор walrus). В отличие от узла
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)))
Индексация¶
- class ast.Subscript(value, slice, ctx)¶
Индекс, такой как
l[1]
.value
, - это объект, на который делается подписка (обычно это последовательность или отображение).slice
- это индекс, фрагмент или ключ. Это может бытьTuple
и содержатьSlice
.ctx
isLoad
,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
- это объект для итерации over.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
- логическое целое число, которому присвоено значение 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)], 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.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
предложения не имеют специального представления в PAST, а скорее отображаются как дополнительные узлы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
.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=[])
- 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
узлов с различными регистрами.
- 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()), patterns=[], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- 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))])])], type_ignores=[])
- 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=[])
- 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=[])
- 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=[])
- class ast.MatchMapping(keys, patterns, rest)¶
Шаблон сопоставления соответствия.
keys
- это последовательность узлов выражения.patterns
- это соответствующая последовательность узлов шаблона.rest
- это необязательное имя, которое можно указать для отображения остальных элементов сопоставления. Разрешенные ключевые выражения ограничены, как описано в документации к инструкции match.Этот шаблон выполняется успешно, если объектом является отображение, все вычисленные ключевые выражения присутствуют в отображении, а значение, соответствующее каждому ключу, соответствует соответствующему подшаблону. Если
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(keys=[], patterns=[], rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- 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))], 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=[])
- 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))])])], type_ignores=[])
- class ast.MatchOr(patterns)¶
Сопоставление с «шаблоном or». Шаблон or по очереди сопоставляет каждый из своих подшаблонов с объектом, пока один из них не завершится успешно. Затем шаблон or считается успешным. Если ни один из подшаблонов не завершается успешно, шаблон 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))])])], type_ignores=[])
Определения функций и классов¶
- class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment)¶
Определение функции.
name
- это необработанная строка имени функции.args
- это узелarguments
.body
- это список узлов внутри функции.decorator_list
- это список применяемых декораторов, который хранится самым первым (т.е. первый в списке будет применен последним).returns
- это аннотация к возврату.
- type_comment¶
type_comment
- это необязательная строка с типом аннотации в качестве комментария.
- 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_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)¶
Определение класса.
name
- это необработанная строка для имени классаbases
- это список узлов для явно указанных базовых классов.keywords
- это список узловkeyword
, в основном для «метакласса». В метакласс будут переданы другие ключевые слова, как указано в PEP-3115.body
- это список узлов, представляющих код в определении класса.decorator_list
- это список узлов, как вFunctionDef
.
>>> 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_ignores=[])
Асинхронность и ожидание¶
- class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment)¶
Определение функции
async def
. Содержит те же поля, что иFunctionDef
.
- 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_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
.Если исходный код содержит символ null, то возникает значение (
\0
),ValueError
.Предупреждение
Обратите внимание, что успешный разбор исходного кода в объект AST не гарантирует, что предоставленный исходный код является допустимым кодом на Python, который может быть выполнен на этапе компиляции, что может привести к дополнительным исключениям
SyntaxError
. Например, исходный кодreturn 42
генерирует допустимый AST-узел для инструкции return, но он не может быть скомпилирован сам по себе (он должен находиться внутри функционального узла).В частности,
ast.parse()
не будет выполнять никаких проверок области видимости, которые выполняются на этапе компиляции.Предупреждение
Возможно аварийное завершение работы интерпретатора Python с достаточно большой/ сложной строкой из-за ограничений глубины стека в AST-компиляторе 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: строки, байты, числа, кортежи, списки, dicts, множества, логические значения,
None
иEllipsis
.Это может быть использовано для вычисления строк, содержащих значения Python, без необходимости разбора значений самостоятельно. Он не способен вычислять произвольно сложные выражения, например, с использованием операторов или индексации.
В прошлом эта функция была задокументирована как «безопасная», но не было указано, что это означает. Это вводило в заблуждение. Она специально разработана для того, чтобы не выполнять код на Python, в отличие от более общего
eval()
. В нем нет пространства имен, нет поиска по имени или возможности вызова. Но он не защищен от атак: относительно небольшой ввод может привести к исчерпанию памяти или стека C, что приведет к сбою процесса. Также существует вероятность отказа в обслуживании при чрезмерном потреблении ресурсов процессора для некоторых входных данных. Поэтому не рекомендуется вызывать его для ненадежных данных.Предупреждение
Интерпретатор Python может привести к сбою из-за ограничений глубины стека в AST-компиляторе Python.
Это может привести к возникновению
ValueError
,TypeError
,SyntaxError
,MemoryError
иRecursionError
в зависимости от неправильного ввода.Изменено в версии 3.2: Теперь разрешены байты и литералы set.
Изменено в версии 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)¶
Получите сегмент исходного кода источника, который сгенерировал узел. Если какая-то информация о местоположении (
lineno
,end_lineno
,col_offset
, илиend_col_offset
) отсутствует, вернитеNone
.Если значение дополнено равно
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)¶
Выведите кортеж из
(fieldname, value)
для каждого поля вnode._fields
, которое присутствует в узле.
- ast.iter_child_nodes(node)¶
Возвращает все прямые дочерние узлы node, то есть все поля, которые являются узлами, и все элементы полей, которые являются списками узлов.
- ast.walk(node)¶
Рекурсивно возвращает все узлы-потомки в дереве, начиная с node (включая сам node), в произвольном порядке. Это полезно, если вы хотите изменить только узлы на месте и не заботитесь о контексте.
- class ast.NodeVisitor¶
Базовый класс посетителя узла, который просматривает абстрактное синтаксическое дерево и вызывает функцию посетителя для каждого найденного узла. Эта функция может возвращать значение, которое передается методом
visit()
.Этот класс предназначен для создания подкласса, в который добавляются методы visitor.
- visit(node)¶
Посетите узел. Реализация по умолчанию вызывает метод с именем
self.visit_classname
, где classname - это имя класса узла, илиgeneric_visit()
, если этот метод не существует.
- generic_visit(node)¶
Этот посетитель вызывает
visit()
для всех дочерних узлов узла.Обратите внимание, что дочерние узлы узлов, у которых есть пользовательский метод visitor, не будут посещены, если посетитель не вызовет
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 и использовать возвращаемое значение методов visitor для замены или удаления старого узла. Если возвращаемое значение метода visitor равно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: Добавлена опция отступ.
Флаги компилятора¶
Следующие флаги могут быть переданы в 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¶
Включите такие атрибуты, как номера строк и смещения столбцов.
Если указано значение infile
, его содержимое автоматически обрабатывается и выводится в стандартный вывод. В противном случае содержимое считывается из стандартного ввода.
См.также
Green Tree Snakes, внешний ресурс документации, содержит подробные сведения о работе с Python AST.
ASTTokens аннотирует Python AST с указанием расположения токенов и текста в исходном коде, который их сгенерировал. Это полезно для инструментов, которые выполняют преобразования исходного кода.
leoAst.py объединяет представления программ на python на основе токенов и дерева синтаксического анализа, вставляя двусторонние ссылки между токенами и узлами ast.
LibCST анализирует код в виде конкретного синтаксического дерева, которое выглядит как ast-дерево и сохраняет все детали форматирования. Это полезно для создания приложений автоматического рефакторинга (code mod) и линтеров.
Parso - это синтаксический анализатор Python, который поддерживает восстановление после ошибок и повторный анализ для разных версий Python (в нескольких версиях Python). Person также может перечислить несколько синтаксических ошибок в вашем файле python.