ast --- درخت‌های سینتکس انتزاعی

کد منبع: Lib/ast.py


ماژول ast به برنامه‌های پایتون کمک می‌کند تا درخت‌های دستور زبان سینتکس انتزاعی پایتون را پردازش کنند. خود سینتکس انتزاعی ممکن است با هر انتشار پایتون تغییر کند؛ این ماژول به شما کمک می‌کند تا به‌صورت برنامه‌ای دریابید دستور زبان جاری چگونه است.

می‌توان یک درخت سینتکس انتزاعی را با ارسال ast.PyCF_ONLY_AST به‌عنوان پرچم به تابع توکار compile() یا با استفاده از تابع کمکی parse() ارائه‌شده در این ماژول، تولید کرد. نتیجه درختی از اشیاء خواهد بود که کلاس‌های آن همگی از ast.AST ارث‌بری می‌کنند. می‌توان یک درخت سینتکس انتزاعی را با استفاده از تابع توکار 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)
         | Interpolation(expr value, constant str, int conversion, expr? format_spec)
         | JoinedStr(expr* values)
         | TemplateStr(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 مشتق شده‌اند، که در بالا بازتولید شده است. آن‌ها در ماژول C _ast تعریف شده‌اند و در ast دوباره اکسپورت شده‌اند.

برای هر نماد سمت چپ در دستور زبان انتزاعی، یک کلاس تعریف شده است (برای مثال، ast.stmt یا ast.expr). علاوه بر این، برای هر سازنده در سمت راست، یک کلاس تعریف شده است؛ این کلاس‌ها از کلاس‌های مربوط به درخت‌های سمت چپ ارث می‌برند. برای مثال، ast.BinOp از ast.expr ارث می‌برد. برای قواعد تولید دارای جایگزین‌ها (معروف به «مجموع‌ها»)، کلاس سمت چپ انتزاعی است: تنها نمونه‌هایی از گره‌های سازنده‌ی خاص ایجاد می‌شوند.

_fields

هر کلاس عینی یک ویژگی _fields دارد که نام همه‌ی گره‌های فرزند را می‌دهد.

هر نمونه از یک کلاس مشخص، به ازای هر گره فرزند یک ویژگی دارد که نوع آن در گرامر تعریف شده است. برای مثال، نمونه‌های ast.BinOp یک ویژگی left از نوع ast.expr دارند.

اگر این ویژگی‌ها در گرامر به‌عنوان اختیاری علامت‌گذاری شده باشند (با استفاده از علامت سؤال)، مقدار ممکن است None باشد. اگر ویژگی‌ها بتوانند صفر یا بیشتر مقدار داشته باشند (با ستاره علامت‌گذاری شده باشند)، مقادیر به‌صورت فهرست‌های پایتون نمایش داده می‌شوند. هنگام کامپایل یک AST با compile()، تمام ویژگی‌های ممکن باید موجود باشند و مقادیر معتبر داشته باشند.

_field_types

ویژگی _field_types در هر کلاس عینی، یک دیکشنری است که نام فیلدها (که در _fields نیز فهرست شده‌اند) را به نوع آن‌ها نگاشت می‌کند.

>>> ast.TypeVar._field_types
{'name': <class 'str'>, 'bound': ast.expr | None, 'default_value': ast.expr | None}

اضافه شده در نسخه‌ی 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 شماره‌های خط اول و آخر بازه‌ی متن منبع هستند (با اندیس ۱، بنابراین اولین خط، خط ۱ است) و 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 این فیلد را نخواهد داشت. در پایتون 3.15، این وضعیت یک خطا پرتاب خواهد کرد.

تغییر یافته در نسخه‌ی 3.8: اکنون از کلاس ast.Constant برای همه‌ی ثابت‌ها استفاده می‌شود.

تغییر یافته در نسخه‌ی 3.9: اندیس‌های ساده با مقدارشان نمایش داده می‌شوند، اسلایس‌های گسترده (extended slices) به‌صورت تاپل‌ها نمایش داده می‌شوند.

تغییر یافته در نسخه‌ی 3.13: سازنده‌های گره AST تغییر کردند تا پیش‌فرض‌های معقولی برای فیلدهای از قلم افتاده فراهم کنند: اکنون مقدار پیش‌فرض فیلدهای اختیاری None است، مقدار پیش‌فرض فیلدهای فهرستی یک فهرست خالی است، و مقدار پیش‌فرض فیلدهایی از نوع ast.expr_context برابر Load() است. پیش از این، ویژگی‌های از قلم افتاده در گره‌های ساخته‌شده وجود نداشتند (دسترسی به آن‌ها باعث پرتاب AttributeError می‌شد).

تغییر یافته در نسخه‌ی 3.14: خروجی __repr__() گره‌های AST شامل مقادیر فیلدهای گره است.

منسوخ شده از نسخه‌ی 3.8، در نسخه‌ی 3.14 حذف شده است: نسخه‌های پیشین پایتون، کلاس‌های AST یعنی ast.Num، ast.Str، ast.Bytes، ast.NameConstant و ast.Ellipsis را فراهم می‌کردند که در پایتون 3.8 منسوخ شده بودند. این کلاس‌ها در پایتون 3.14 حذف شدند و کارکرد آن‌ها با ast.Constant جایگزین شده است.

منسوخ شده از نسخه‌ی 3.9: کلاس‌های قدیمی ast.Index و ast.ExtSlice هنوز در دسترس هستند، اما در نسخه‌های آینده پایتون حذف خواهند شد. تا آن زمان، نمونه‌سازی از آن‌ها یک نمونه از کلاسی دیگر را برمی‌گرداند.

منسوخ شده از نسخه‌ی 3.13, در نسخه‌ی 3.15 حذف خواهد شد: نسخه‌های پیشین پایتون امکان ایجاد گره‌های AST را که فاقد فیلدهای الزامی بودند، می‌دادند. به‌طور مشابه، سازنده‌های گره AST اجازه می‌دادند آرگومان‌های کلیدواژه‌ای دلخواه به‌عنوان ویژگی‌های گره AST تنظیم شوند، حتی اگر با هیچ‌یک از فیلدهای گره AST مطابقت نداشتند. این رفتار منسوخ‌شده است و در پایتون 3.15 حذف خواهد شد.

توجه

توضیحات کلاس‌های گره خاصی که در اینجا نمایش داده شده‌اند، در ابتدا از پروژه‌ی فوق‌العاده‌ی Green Tree Snakes و همه‌ی مشارکت‌کنندگان آن اقتباس شده‌اند.

گره‌های ریشه

class ast.Module(body, type_ignores)

یک ماژول پایتون، مانند ورودی پرونده. نوع گره‌ای که توسط 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)

یک ورودی عبارت پایتون. نوع گره‌ای که توسط ast.parse() هنگامی که mode برابر "eval" باشد، تولید می‌شود.

body یک گره واحد است، یکی از انواع عبارت.

>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4))
Expression(
    body=Constant(value=123))
class ast.Interactive(body)

یک ورودی تعاملی واحد، مانند حالت تعاملی. نوع گره تولیدشده توسط ast.parse() هنگامی که mode برابر "single" است.

body یک list از گره‌های دستور است.

>>> print(ast.dump(ast.parse('x = 1; y = 2', mode='single'), indent=4))
Interactive(
    body=[
        Assign(
            targets=[
                Name(id='x', ctx=Store())],
            value=Constant(value=1)),
        Assign(
            targets=[
                Name(id='y', ctx=Store())],
            value=Constant(value=2))])
class ast.FunctionType(argtypes, returns)

بازنمایی‌ای از کامنت‌های نوع به سبک قدیمی برای توابع، زیرا نسخه‌های پایتون پیش از 3.5 از حاشیه‌نویسی‌های PEP 484 پشتیبانی نمی‌کردند. نوع گره تولیدشده توسط ast.parse() هنگامی که mode برابر "func_type" باشد.

چنین کامنت‌های نوعی به این شکل خواهند بود:

def sum_two_number(a, b):
    # type: (int, int) -> int
    return a + b

argtypes یک list از گره‌های عبارت است.

returns یک گره عبارت است.

>>> print(ast.dump(ast.parse('(int, str) -> List[int]', mode='func_type'), indent=4))
FunctionType(
    argtypes=[
        Name(id='int', ctx=Load()),
        Name(id='str', ctx=Load())],
    returns=Subscript(
        value=Name(id='List', ctx=Load()),
        slice=Name(id='int', ctx=Load()),
        ctx=Load()))

اضافه شده در نسخه‌ی 3.8.

مقادیر لفظی

class ast.Constant(value, kind)

یک مقدار ثابت. ویژگی value در لفظی Constant شامل شیء پایتونی بازنمایی‌شده توسط آن است. مقادیر بازنمایی‌شده می‌توانند نمونه‌هایی از str، bytes، int، float، complex و bool، و ثابت‌های None و Ellipsis باشند.

ویژگی kind یک رشته اختیاری است. برای مقادیر لفظی رشته‌ای با پیشوند u، kind روی 'u' تنظیم می‌شود. برای همه‌ی ثابت‌های دیگر، kind برابر None است.

>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4))
Expression(
    body=Constant(value=123))
>>> print(ast.dump(ast.parse("u'hello'", mode='eval'), indent=4))
Expression(
    body=Constant(value='hello', kind='u'))
class ast.FormattedValue(value, conversion, format_spec)

گره‌ای که نشان‌دهنده‌ی یک فیلد قالب‌بندی منفرد در یک اف‌استرینگ است. اگر رشته شامل یک فیلد قالب‌بندی منفرد و هیچ چیز دیگری باشد، گره می‌تواند جداگانه باشد؛ در غیر این صورت در JoinedStr ظاهر می‌شود.

  • value هر گره عبارتی است (مانند یک لفظی، یک متغیر، یا یک فراخوانی تابع).

  • conversion یک عدد صحیح است:

    • -1: بدون قالب‌بندی

    • ۹۷ (ord('a')): !a قالب‌بندی ASCII

    • ۱۱۴ (ord('r')): قالب‌بندی !r با repr()

    • ۱۱۵ (ord('s')): !s قالب‌بندی string

  • format_spec یک گره JoinedStr است که قالب‌بندی مقدار را نشان می‌دهد، یا اگر قالبی مشخص نشده باشد، None است. هر دو conversion و format_spec را می‌توان همزمان تنظیم کرد.

class ast.JoinedStr(values)

یک اف‌استرینگ، شامل مجموعه‌ای از گره‌های 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.TemplateStr(values, /)

اضافه شده در نسخه‌ی 3.14.

گره‌ای که یک لفظی رشته‌ی الگویی (template string literal) را نشان می‌دهد و شامل دنباله‌ای از گره‌های Interpolation و Constant است. این گره‌ها می‌توانند به هر ترتیبی باشند و نیازی نیست به‌صورت یک‌درمیان باشند.

>>> expr = ast.parse('t"{name} finished {place:ordinal}"', mode='eval')
>>> print(ast.dump(expr, indent=4))
Expression(
    body=TemplateStr(
        values=[
            Interpolation(
                value=Name(id='name', ctx=Load()),
                str='name',
                conversion=-1),
            Constant(value=' finished '),
            Interpolation(
                value=Name(id='place', ctx=Load()),
                str='place',
                conversion=-1,
                format_spec=JoinedStr(
                    values=[
                        Constant(value='ordinal')]))]))
class ast.Interpolation(value, str, conversion, format_spec=None)

اضافه شده در نسخه‌ی 3.14.

گره‌ای که نشان‌دهنده‌ی یک فیلد درون‌یابی (interpolation field) در یک لفظی رشته‌ی الگو است.

  • value می‌تواند هر گره‌ی عبارت باشد (مانند یک لفظی، یک متغیر، یا یک فراخوانی تابع). این همان معنای FormattedValue.value را دارد.

  • str یک ثابت است که حاوی متن عبارت درون‌یابی است.

    اگر str روی None تنظیم شود، هنگام فراخوانی ast.unparse() از value برای تولید کد استفاده می‌شود. در این حالت دیگر تضمین نمی‌شود که کد تولیدشده با کد اصلی یکسان باشد و این برای تولید کد در نظر گرفته شده است.

  • conversion یک عدد صحیح است:

    • -1: بدون تبدیل

    • ۹۷ (ord('a')): تبدیل !a به ASCII

    • ۱۱۴ (ord('r')): تبدیل !r به repr()

    • ۱۱۵ (ord('s')): تبدیل string با !s

    این همان معنای FormattedValue.conversion را دارد.

  • format_spec یک گره JoinedStr است که قالب‌بندی مقدار را نشان می‌دهد، یا اگر هیچ قالبی مشخص نشده باشد، None است. می‌توان هر دو conversion و format_spec را همزمان تنظیم کرد. این همان معنای FormattedValue.format_spec را دارد.

class ast.List(elts, ctx)
class ast.Tuple(elts, ctx)

یک فهرست یا تاپل. elts شامل فهرستی از گره‌های نشان‌دهنده عناصر است. اگر ظرف هدف انتساب باشد (یعنی (x,y)=somethingctx Store است و در غیر این صورت 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)

یک عملیات بولی، 'or' یا 'and'. op Or یا And است. values مقادیر درگیر هستند. عملیات‌های متوالی با همان عملگر، مانند a or b or c، در یک گره با چند مقدار ادغام می‌شوند.

این شامل not نمی‌شود، که یک UnaryOp است.

>>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4))
Expression(
    body=BoolOp(
        op=Or(),
        values=[
            Name(id='x', ctx=Load()),
            Name(id='y', ctx=Load())]))
class ast.And
class ast.Or

توکن‌های عملگر بولی.

class ast.Compare(left, ops, comparators)

مقایسه‌ی دو یا چند مقدار. left نخستین مقدار در مقایسه است، ops فهرست عملگرها است، و comparators فهرست مقادیر پس از نخستین عنصر در مقایسه است.

>>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4))
Expression(
    body=Compare(
        left=Constant(value=1),
        ops=[
            LtE(),
            Lt()],
        comparators=[
            Name(id='a', ctx=Load()),
            Constant(value=10)]))
class ast.Eq
class ast.NotEq
class ast.Lt
class ast.LtE
class ast.Gt
class ast.GtE
class ast.Is
class ast.IsNot
class ast.In
class ast.NotIn

توکن‌های عملگر مقایسه‌ای.

class ast.Call(func, args, keywords)

یک فراخوانی تابع. func تابع است، که اغلب یک شیء Name یا Attribute خواهد بود. از میان آرگومان‌ها:

  • args فهرستی از آرگومان‌های ارسال‌شده به‌صورت جایگاهی را در خود نگه می‌دارد.

  • keywords شامل فهرستی از اشیاء keyword است که آرگومان‌های ارسال‌شده با کلیدواژه را نشان می‌دهند.

آرگومان‌های 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 توسط عملگر عبارت انتساب (که به عملگر 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)))

اضافه شده در نسخه‌ی 3.8.

زیرنویس‌گذاری

class ast.Subscript(value, slice, ctx)

یک زیرنویس (subscript)، مانند 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 نشان می‌دهد که یک درک ناهمگام است (به جای for از async for استفاده می‌کند). مقدار آن یک عدد صحیح (۰ یا ۱) است.

>>> 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 همیشه یا ۰ است (نشان‌دهنده‌ی یک هدف «پیچیده») یا ۱ (نشان‌دهنده‌ی یک هدف «ساده»). یک هدف «ساده» فقط شامل یک گره Name است که بین پرانتز قرار ندارد؛ تمام اهداف دیگر پیچیده محسوب می‌شوند. تنها اهداف ساده در دیکشنری __annotations__ ماژول‌ها و کلاس‌ها ظاهر می‌شوند.

>>> print(ast.dump(ast.parse('c: int'), indent=4))
Module(
    body=[
        AnnAssign(
            target=Name(id='c', ctx=Store()),
            annotation=Name(id='int', ctx=Load()),
            simple=1)])

>>> 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 با مقدار ۱ است.

ویژگی 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 ایجاد شده است. name نام این نام مستعار است، type_params فهرستی از پارامترهای نوع است، و 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()))])

اضافه شده در نسخه‌ی 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 یک عدد صحیح است که سطح ایمپورت نسبی را نگه می‌دارد (۰ به معنای ایمپورت مطلق است).

>>> 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))])])])

اضافه شده در نسخه‌ی 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 برای حالت‌های مختلف است.

اضافه شده در نسخه‌ی 3.10.

class ast.match_case(pattern, guard, body)

یک الگوی case منفرد در یک دستور match. pattern شامل الگوی تطبیقی است که موضوع با آن تطبیق داده خواهد شد. توجه داشته باشید که گره‌های AST تولیدشده برای الگوها با گره‌های تولیدشده برای عبارات متفاوت هستند، حتی زمانی که سینتکس یکسانی دارند.

ویژگی guard شامل عبارتی است که اگر الگو با موضوع مطابقت داشته باشد، ارزیابی می‌شود.

body شامل فهرستی از گره‌هاست که در صورتی اجرا می‌شوند که الگو مطابقت داشته باشد و نتیجه ارزیابی عبارت نگهبان درست باشد.

>>> print(ast.dump(ast.parse("""
... match x:
...     case [x] if x>0:
...         ...
...     case tuple():
...         ...
... """), indent=4))
Module(
    body=[
        Match(
            subject=Name(id='x', ctx=Load()),
            cases=[
                match_case(
                    pattern=MatchSequence(
                        patterns=[
                            MatchAs(name='x')]),
                    guard=Compare(
                        left=Name(id='x', ctx=Load()),
                        ops=[
                            Gt()],
                        comparators=[
                            Constant(value=0)]),
                    body=[
                        Expr(
                            value=Constant(value=Ellipsis))]),
                match_case(
                    pattern=MatchClass(
                        cls=Name(id='tuple', ctx=Load())),
                    body=[
                        Expr(
                            value=Constant(value=Ellipsis))])])])

اضافه شده در نسخه‌ی 3.10.

class ast.MatchValue(value)

یک لفظی تطبیق یا الگوی مقدار که بر اساس برابری مقایسه می‌کند. value یک گره عبارت است. گره‌های مقدار مجاز، همان‌طور که در مستندات دستور تطبیق توضیح داده‌شده است، محدود شده‌اند. این الگو در صورتی موفق می‌شود که موضوع تطبیق با مقدار ارزیابی‌شده برابر باشد.

>>> print(ast.dump(ast.parse("""
... match x:
...     case "Relevant":
...         ...
... """), indent=4))
Module(
    body=[
        Match(
            subject=Name(id='x', ctx=Load()),
            cases=[
                match_case(
                    pattern=MatchValue(
                        value=Constant(value='Relevant')),
                    body=[
                        Expr(
                            value=Constant(value=Ellipsis))])])])

اضافه شده در نسخه‌ی 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))])])])

اضافه شده در نسخه‌ی 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))])])])

اضافه شده در نسخه‌ی 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))])])])

اضافه شده در نسخه‌ی 3.10.

class ast.MatchMapping(keys, patterns, rest)

یک الگوی نگاشت تطبیق. keys دنباله‌ای از گره‌های عبارت است. patterns دنباله‌ای متناظر از گره‌های الگو است. rest نامی اختیاری است که می‌توان آن را برای گرفتن عناصر باقی‌مانده‌ی نگاشت مشخص کرد. عبارات مجاز برای کلیدها، همان‌طور که در مستندات دستور match توضیح داده شده است، محدود شده‌اند.

این الگو زمانی موفق می‌شود که موضوع یک نگاشت باشد، همه عبارت‌های کلید ارزیابی‌شده در نگاشت وجود داشته باشند، و مقدار متناظر با هر کلید با زیرالگوی متناظر مطابقت داشته باشد. اگر rest برابر None نباشد، یک دیکشنری شامل عناصر باقی‌مانده نگاشت، در صورت موفقیت کل الگوی نگاشت، به آن نام مقید می‌شود.

>>> print(ast.dump(ast.parse("""
... match x:
...     case {1: _, 2: _}:
...         ...
...     case {**rest}:
...         ...
... """), indent=4))
Module(
    body=[
        Match(
            subject=Name(id='x', ctx=Load()),
            cases=[
                match_case(
                    pattern=MatchMapping(
                        keys=[
                            Constant(value=1),
                            Constant(value=2)],
                        patterns=[
                            MatchAs(),
                            MatchAs()]),
                    body=[
                        Expr(
                            value=Constant(value=Ellipsis))]),
                match_case(
                    pattern=MatchMapping(rest='rest'),
                    body=[
                        Expr(
                            value=Constant(value=Ellipsis))])])])

اضافه شده در نسخه‌ی 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))])])])

اضافه شده در نسخه‌ی 3.10.

class ast.MatchAs(pattern, name)

یک «الگوی as» (as-pattern) در تطبیق، یک الگوی ثبت‌کننده (capture pattern) یا یک الگوی wildcard (wildcard pattern). 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))])])])

اضافه شده در نسخه‌ی 3.10.

class ast.MatchOr(patterns)

یک «الگوی یا» (or-pattern) در تطبیق. یک الگوی یا هر یک از الگوهای فرعی خود را به‌نوبت با موضوع تطبیق می‌دهد، تا یکی موفق شود. سپس الگوی یا موفق تلقی می‌شود. اگر هیچ‌کدام از الگوهای فرعی موفق نشوند، الگوی یا شکست می‌خورد. ویژگی 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))])])])

اضافه شده در نسخه‌ی 3.10.

حاشیه‌نویسی‌های نوع

class ast.TypeIgnore(lineno, tag)

یک کامنت # type: ignore در lineno قرار دارد. tag برچسب اختیاری است که با قالب # type: ignore <tag> مشخص می‌شود.

>>> print(ast.dump(ast.parse('x = 1 # type: ignore', type_comments=True), indent=4))
Module(
    body=[
        Assign(
            targets=[
                Name(id='x', ctx=Store())],
            value=Constant(value=1))],
    type_ignores=[
        TypeIgnore(lineno=1, tag='')])
>>> print(ast.dump(ast.parse('x: bool = 1 # type: ignore[assignment]', type_comments=True), indent=4))
Module(
    body=[
        AnnAssign(
            target=Name(id='x', ctx=Store()),
            annotation=Name(id='bool', ctx=Load()),
            value=Constant(value=1),
            simple=1)],
    type_ignores=[
        TypeIgnore(lineno=1, tag='[assignment]')])

توجه

گره‌های TypeIgnore زمانی که پارامتر type_comments روی False (پیش‌فرض) تنظیم شده باشد، ایجاد نمی‌شوند. برای جزئیات بیشتر ast.parse() را ببینید.

اضافه شده در نسخه‌ی 3.8.

پارامترهای نوع

پارامترهای نوع می‌توانند در کلاس‌ها، توابع و نام‌های مستعار نوع وجود داشته باشند.

class ast.TypeVar(name, bound, default_value)

یک 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()))])

اضافه شده در نسخه‌ی 3.12.

تغییر یافته در نسخه‌ی 3.13: پارامتر default_value افزوده شد.

class ast.ParamSpec(name, default_value)

یک 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=List(
                        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()))])

اضافه شده در نسخه‌ی 3.12.

تغییر یافته در نسخه‌ی 3.13: پارامتر default_value افزوده شد.

class ast.TypeVarTuple(name, default_value)

یک 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()))])

اضافه شده در نسخه‌ی 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 حاشیه‌نویسی بازگشت (return annotation) است.

  • type_params فهرستی از پارامترهای نوع است.

type_comment

type_comment یک رشته اختیاری حاوی حاشیه‌نویسی نوع به‌صورت کامنت است.

تغییر یافته در نسخه‌ی 3.12: type_params اضافه شد.

class ast.Lambda(args, body)

lambda یک تعریف حداقلی تابع است که می‌تواند درون یک عبارت استفاده شود. برخلاف FunctionDef، body تنها شامل یک گره است.

>>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4))
Module(
    body=[
        Expr(
            value=Lambda(
                args=arguments(
                    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 فهرستی از پارامترهای نوع است.

>>> 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 اضافه شد.

ناهمگام و await

class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment, type_params)

یک تعریف تابع async def. دارای همان فیلدهای FunctionDef است.

تغییر یافته در نسخه‌ی 3.12: type_params اضافه شد.

class ast.Await(value)

یک عبارت await. value مقداری است که برای آن انتظار می‌رود. فقط در بدنه‌ی یک AsyncFunctionDef معتبر است.

>>> print(ast.dump(ast.parse("""\
... async def f():
...     await other_func()
... """), indent=4))
Module(
    body=[
        AsyncFunctionDef(
            name='f',
            args=arguments(),
            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 اگر optimize <= 0 باشد ast.PyCF_ONLY_AST و در غیر این صورت 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 برگردانده می‌شوند (در غیر این صورت همیشه یک فهرست خالی است).

In addition, if mode is 'func_type', the input syntax is modified to correspond to PEP 484 "signature type comments", for example (str, int) -> List[str].

تنظیم feature_version به یک تاپل (major, minor) منجر به تلاش «بهترین تلاش» برای تجزیه با استفاده از دستور زبان آن نسخه از پایتون می‌شود. برای مثال، تنظیم feature_version=(3, 9) تلاش می‌کند تجزیه‌ی دستورهای match را غیرمجاز کند. در حال حاضر major باید برابر با 3 باشد. کمترین نسخه‌ی پشتیبانی‌شده (3, 7) است (و ممکن است در نسخه‌های آینده‌ی پایتون افزایش یابد)؛ بیشترین نسخه sys.version_info[0:2] است. تلاش «بهترین تلاش» به این معناست که تضمینی وجود ندارد که تجزیه (یا موفقیت تجزیه) همانند حالتی باشد که در نسخه‌ی پایتون متناظر با feature_version اجرا می‌شود.

اگر source حاوی یک نویسه‌ی نال (\0) باشد، ValueError پرتاب می‌شود.

هشدار

توجه داشته باشید که تجزیه‌ی موفقیت‌آمیز کد منبع به یک شیء AST تضمین نمی‌کند که کد منبع ارائه‌شده، کد پایتون معتبری باشد که بتواند اجرا شود، زیرا مرحله‌ی کامپایل می‌تواند استثناهای بیشتری از نوع SyntaxError پرتاب کند. برای مثال، کد منبع return 42 یک گره AST معتبر برای یک دستور return تولید می‌کند، اما نمی‌تواند به‌تنهایی کامپایل شود (باید داخل یک گره تابع باشد).

به‌طور خاص، ast.parse() هیچ‌گونه بررسی محدوده‌ای انجام نمی‌دهد، در حالی که مرحله‌ی کامپایل این کار را انجام می‌دهد.

هشدار

ممکن است مفسر پایتون به دلیل محدودیت‌های عمق پشته در کامپایلر AST پایتون، با رشته‌ای به‌اندازه کافی بزرگ/پیچیده از کار بیفتد.

تغییر یافته در نسخه‌ی 3.8: type_comments، mode='func_type' و feature_version افزوده شد.

تغییر یافته در نسخه‌ی 3.13: حداقل نسخه پشتیبانی‌شده برای feature_version اکنون (3, 7) است. آرگومان optimize افزوده شد.

ast.unparse(ast_obj)

یک شیء ast.AST را به کد بازگردانید و رشته‌ای حاوی کدی تولید کنید که اگر دوباره با ast.parse() تجزیه شود، یک شیء ast.AST معادل تولید می‌کند.

هشدار

رشته‌ی کد تولیدشده لزوماً با کد اصلی که شیء ast.AST را تولید کرده است برابر نخواهد بود (بدون هیچ‌گونه بهینه‌سازی کامپایلر، مانند تاپل‌ها/فروزن‌ست‌های ثابت).

هشدار

تلاش برای بازگردانی (unparse) یک عبارت بسیار پیچیده منجر به RecursionError می‌شود.

اضافه شده در نسخه‌ی 3.9.

ast.literal_eval(node_or_string)

یک گره عبارت یا رشته‌ای را که فقط شامل یک لفظی پایتون یا نمایش ظرف (container display) باشد، ارزیابی می‌کند. رشته یا گره ارائه‌شده فقط می‌تواند شامل ساختارهای لفظی پایتون زیر باشد: رشته‌ها، بایت‌ها، اعداد، تاپل‌ها، فهرست‌ها، دیکشنری‌ها، مجموعه‌ها، بولی‌ها، None و Ellipsis.

می‌توان از این برای ارزیابی رشته‌های حاوی مقادیر پایتون استفاده کرد، بدون نیاز به اینکه خودتان مقادیر را تجزیه کنید. این مورد قادر به ارزیابی عبارت‌های با پیچیدگی دلخواه نیست، برای مثال عبارت‌هایی که شامل عملگرها یا اندیس‌دهی باشند.

این تابع در گذشته بدون این‌که تعریف شود منظور از «امن» چیست، به‌عنوان «امن» مستند شده بود. این موضوع گمراه‌کننده بود. این تابع به‌طور خاص به‌گونه‌ای طراحی شده است که برخلاف eval() که عمومی‌تر است، کد پایتون را اجرا نکند. هیچ فضای نامی وجود ندارد، هیچ جست‌وجوی نامی انجام نمی‌شود، و هیچ امکانی برای فراخوانی بیرونی وجود ندارد. اما این تابع از حملات مصون نیست: یک ورودی نسبتاً کوچک می‌تواند به اتمام حافظه یا اتمام پشته C منجر شود و فرایند را از کار بیندازد. همچنین امکان ایجاد منع سرویس ناشی از مصرف بیش‌ازحد CPU در برخی ورودی‌ها وجود دارد. بنابراین فراخوانی آن با داده‌های غیرقابل‌اعتماد توصیه نمی‌شود.

هشدار

ممکن است مفسر پایتون به دلیل محدودیت‌های عمق پشته در کامپایلر AST پایتون از کار بیفتد.

ممکن است بسته به ورودی نامعتبر، ValueError، TypeError، SyntaxError، MemoryError و RecursionError پرتاب شوند.

تغییر یافته در نسخه‌ی 3.2: اکنون مقادیر لفظی bytes و set را می‌پذیرد.

تغییر یافته در نسخه‌ی 3.9: اکنون از ایجاد مجموعه‌های خالی با 'set()' پشتیبانی می‌شود.

تغییر یافته در نسخه‌ی 3.10: برای ورودی‌های رشته‌ای، فاصله‌ها و تب‌های ابتدایی اکنون حذف می‌شوند.

ast.get_docstring(node, clean=True)

رشته مستندات مربوط به node داده‌شده را برمی‌گرداند (که باید یک گره از نوع FunctionDef، AsyncFunctionDef، ClassDef یا Module باشد)، یا اگر رشته مستندات نداشته باشد، None را برمی‌گرداند. اگر clean درست باشد، تورفتگی رشته مستندات را با inspect.cleandoc() مرتب می‌کند.

تغییر یافته در نسخه‌ی 3.5: اکنون از AsyncFunctionDef پشتیبانی می‌شود.

ast.get_source_segment(source, node, *, padded=False)

قطعه‌ای از کد منبع source را که node را تولید کرده است، دریافت کنید. اگر برخی از اطلاعات موقعیت (lineno، end_lineno، col_offset، یا end_col_offset) موجود نباشد، None را برگردانید.

اگر padded برابر True باشد، نخستین خط از یک دستور چندخطی با فاصله‌ها پر می‌شود تا با موقعیت اصلی خود مطابقت کند.

اضافه شده در نسخه‌ی 3.8.

ast.fix_missing_locations(node)

هنگامی که یک درخت گره را با compile() کامپایل می‌کنید، کامپایلر انتظار دارد که ویژگی‌های lineno و col_offset برای هر گره‌ای که از آن‌ها پشتیبانی می‌کند، وجود داشته باشند. تنظیم این ویژگی‌ها برای گره‌های تولیدشده نسبتاً خسته‌کننده است، بنابراین این کمک‌کننده این ویژگی‌ها را به‌صورت بازگشتی در مواردی که از قبل تنظیم نشده باشند، با تنظیم آن‌ها به مقادیر گره والد اضافه می‌کند. این کمک‌کننده به‌صورت بازگشتی از node شروع به کار می‌کند.

ast.increment_lineno(node, n=1)

شماره خط و شماره خط پایانی هر گره در درختی که از node شروع می‌شود را به مقدار n افزایش دهید. این کار برای «انتقال کد» به مکانی دیگر در یک پرونده مفید است.

ast.copy_location(new_node, old_node)

در صورت امکان، موقعیت منبع (lineno، col_offset، end_lineno و end_col_offset) را از old_node به new_node کپی کنید و new_node را برگردانید.

ast.iter_fields(node)

برای هر فیلد در node._fields که در node موجود است، یک تاپل از (fieldname, value) تولید می‌کند.

ast.iter_child_nodes(node)

تمام گره‌های فرزند مستقیم node را تولید (yield) می‌کند، یعنی تمام فیلدهایی که گره هستند و تمام آیتم‌های فیلدهایی که فهرست‌هایی از گره‌ها هستند.

ast.walk(node)

به‌صورت بازگشتی تمام گره‌های نواده در درختی که از node شروع می‌شود (از جمله خود node) را، بدون هیچ ترتیب مشخصی، تولید می‌کند. این در صورتی مفید است که فقط بخواهید گره‌ها را درجا تغییر دهید و به زمینه اهمیتی ندهید.

class ast.NodeVisitor

یک کلاس پایه‌ی بازدیدکننده‌ی گره که درخت سینتکس انتزاعی را پیمایش می‌کند و برای هر گره‌ی یافت‌شده، یک تابع بازدیدکننده را فراخوانی می‌کند. این تابع ممکن است مقداری برگرداند که توسط متد visit() ارسال می‌شود.

این کلاس برای زیرکلاس‌سازی در نظر گرفته شده است، به‌طوری که زیرکلاس، متدهای بازدیدکننده (visitor) را اضافه می‌کند.

visit(node)

از یک گره بازدید می‌کند. پیاده‌سازی پیش‌فرض، متدی به نام self.visit_classname را فراخوانی می‌کند که در آن classname نام کلاس گره است، یا اگر آن متد وجود نداشته باشد، generic_visit() را فراخوانی می‌کند.

generic_visit(node)

این بازدیدکننده، visit() را روی تمام فرزندان گره فراخوانی می‌کند.

توجه داشته باشید که گره‌های فرزندِ گره‌هایی که یک متد بازدیدکننده سفارشی دارند، بازدید نخواهند شد، مگر اینکه بازدیدکننده generic_visit() را فراخوانی کند یا خودش آن‌ها را بازدید کند.

visit_Constant(node)

تمام گره‌های ثابت را مدیریت می‌کند.

اگر می‌خواهید در حین پیمایش تغییراتی را به گره‌ها اعمال کنید، از NodeVisitor استفاده نکنید. برای این منظور یک بازدیدکننده ویژه وجود دارد (NodeTransformer) که امکان اصلاح را فراهم می‌کند.

منسوخ شده از نسخه‌ی 3.8، در نسخه‌ی 3.14 حذف شده است: متدهای visit_Num()، visit_Str()، visit_Bytes()، visit_NameConstant() و visit_Ellipsis() در Python 3.14+ فراخوانی نخواهند شد. برای مدیریت همه گره‌های ثابت، در عوض متد visit_Constant() را اضافه کنید.

class ast.NodeTransformer

یک زیرکلاس از NodeVisitor که درخت سینتکس انتزاعی را پیمایش می‌کند و امکان تغییر گره‌ها را فراهم می‌کند.

NodeTransformer درخت سینتکس انتزاعی (AST) را پیمایش می‌کند و از مقدار بازگشتی متدهای بازدیدکننده برای جایگزینی یا حذف گره قدیمی استفاده می‌کند. اگر مقدار بازگشتی متد بازدیدکننده None باشد، گره از موقعیت خود حذف می‌شود، در غیر این صورت با مقدار بازگشتی جایگزین می‌شود. ممکن است مقدار بازگشتی همان گره اصلی باشد که در این صورت هیچ جایگزینی انجام نمی‌شود.

در اینجا یک تبدیل‌کننده (transformer) مثال آمده است که همه‌ی موارد جست‌وجوی نام (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))

معمولاً از تبدیل‌کننده (transformer) به این صورت استفاده می‌کنید:

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 یک عدد صحیح نامنفی یا رشته باشد، درخت با آن سطح تورفتگی به‌صورت خوانا چاپ می‌شود. سطح تورفتگی ۰، منفی، یا "" فقط سطرهای جدید درج می‌کند. None (پیش‌فرض) نمایش تک‌سطری را انتخاب می‌کند. استفاده از تورفتگی عدد صحیح مثبت، در هر سطح به همان تعداد فاصله تورفتگی ایجاد می‌کند. اگر indent یک رشته باشد (مانند "\t")، از آن رشته برای تورفتگی هر سطح استفاده می‌شود.

اگر show_empty نادرست باشد (حالت پیش‌فرض)، فهرست‌های خالی اختیاری از خروجی حذف می‌شوند. مقادیر 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=[])
ast.compare(a, b, /, *, compare_attributes=False)

دو AST را به‌صورت بازگشتی مقایسه می‌کند.

compare_attributes بر اینکه آیا ویژگی‌های AST در مقایسه در نظر گرفته شوند یا خیر، تأثیر می‌گذارد. اگر compare_attributes برابر False (پیش‌فرض) باشد، ویژگی‌ها نادیده گرفته می‌شوند. در غیر این صورت، همه‌ی آن‌ها باید برابر باشند. این گزینه برای بررسی اینکه آیا ASTها از نظر ساختاری برابرند اما در فضای سفید یا جزئیات مشابه تفاوت دارند، مفید است. ویژگی‌ها شامل شماره‌ی سطرها و آفست‌های ستونی هستند.

اضافه شده در نسخه‌ی 3.14.

پرچم‌های کامپایلر

پرچم‌های زیر را می‌توان برای تغییر اثرات بر کامپایل یک برنامه به compile() ارسال کرد:

ast.PyCF_ALLOW_TOP_LEVEL_AWAIT

پشتیبانی از await، async for و async with در سطح بالا و درک‌های ناهمگام را فعال می‌کند.

اضافه شده در نسخه‌ی 3.8.

ast.PyCF_ONLY_AST

به‌جای برگرداندن یک شیء کد کامپایل‌شده، یک درخت سینتکس انتزاعی را تولید می‌کند و برمی‌گرداند.

ast.PyCF_OPTIMIZED_AST

درخت سینتکس انتزاعی (AST) برگردانده‌شده بر اساس آرگومان optimize در compile() یا ast.parse() بهینه‌سازی شده است.

اضافه شده در نسخه‌ی 3.13.

ast.PyCF_TYPE_COMMENTS

پشتیبانی از کامنت‌های نوع به سبک PEP 484 و PEP 526 را فعال می‌کند (# type: <type>، # type: ignore <stuff>).

اضافه شده در نسخه‌ی 3.8.

استفاده از خط فرمان

اضافه شده در نسخه‌ی 3.9.

ماژول ast می‌تواند به‌عنوان یک اسکریپت از خط فرمان اجرا شود. این کار به سادگی زیر است:

python -m ast [-m <mode>] [-a] [infile]

گزینه‌های زیر پذیرفته می‌شوند:

-h, --help

نمایش پیام راهنما و خروج.

-m <mode>
--mode <mode>

مشخص کنید که چه نوع کدی باید کامپایل شود، مانند آرگومان mode در parse().

--no-type-comments

کامنت‌های نوع را تجزیه نکنید.

-a, --include-attributes

شامل ویژگی‌هایی مانند شماره سطرها و آفست‌های ستون (column offsets) باشد.

-i <indent>
--indent <indent>

تورفتگی گره‌ها در AST (تعداد فاصله‌ها).

--feature-version <version>

نسخه پایتون در قالب 3.x (برای مثال، 3.10). پیش‌فرض آن، نسخه فعلی مفسر است.

اضافه شده در نسخه‌ی 3.14.

-O <level>
--optimize <level>

سطح بهینه‌سازی برای پارسر . به‌طور پیش‌فرض بدون بهینه‌سازی است.

اضافه شده در نسخه‌ی 3.14.

--show-empty

نمایش فهرست‌های خالی و فیلدهایی که None هستند. به‌طور پیش‌فرض، اشیاء خالی نمایش داده نمی‌شوند.

اضافه شده در نسخه‌ی 3.14.

اگر infile مشخص شده باشد، محتوای آن به AST تجزیه می‌شود و در stdout نوشته می‌شود. در غیر این صورت، محتوا از stdin خوانده می‌شود.

همچنین ملاحظه نمائید

Green Tree Snakes، یک منبع خارجی مستندات، جزئیات خوبی درباره‌ی کار با ASTهای پایتون دارد.

ASTTokens ASTهای پایتون را با موقعیت‌های توکن‌ها و متن در کد منبعی که آن‌ها را تولید کرده است، حاشیه‌نویسی می‌کند. این موضوع برای ابزارهایی که تبدیل‌هایی روی کد منبع انجام می‌دهند، مفید است.

leoAst.py نمایش‌های مبتنی بر توکن و مبتنی بر درخت تجزیه از برنامه‌های پایتون را با درج پیوندهای دوطرفه میان توکن‌ها و گره‌های AST یکپارچه می‌کند.

LibCST کد را به‌صورت یک درخت سینتکس عینی (Concrete Syntax Tree) تجزیه می‌کند که شبیه به یک درخت ast است و تمام جزئیات قالب‌بندی را حفظ می‌کند. این برای ساخت برنامه‌های بازسازی خودکار (codemod) و لینترها مفید است.

Parso یک پارسر پایتون است که از بازیابی خطا و تجزیه‌ی رفت‌وبرگشتی برای نسخه‌های مختلف پایتون (در چندین نسخه‌ی پایتون) پشتیبانی می‌کند. Parso همچنین می‌تواند چندین خطای سینتکسی را در پرونده پایتون شما فهرست کند.