"ast" --- 抽象語法樹 (Abstract Syntax Trees)
********************************************

**原始碼：**Lib/ast.py

======================================================================

"ast" 模組可以幫助 Python 應用程式處理 Python 抽象語法文法 (abstract
syntax grammar) 樹狀資料結構。抽象語法本身可能會隨著每個 Python 版本發
布而改變；此模組有助於以程式化的方式來得知目前文法的面貌。

要生成抽象語法樹，可以透過將 "ast.PyCF_ONLY_AST" 作為旗標傳遞給內建函
式 "compile()" 或使用此模組所提供的 "parse()" 輔助函式。結果將會是一個
物件的樹，其類別都繼承自 "ast.AST"。可以使用內建的 "compile()" 函式將
抽象語法樹編譯成 Python 程式碼物件。


抽象文法 (Abstract Grammar)
===========================

抽象文法目前定義如下：

   -- 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, int? is_lazy)
             | ImportFrom(identifier? module, alias* names, int? level, int? is_lazy)

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


節點 (Node) 類別
================

class ast.AST

   This is the abstract base of all AST node classes.  The actual node
   classes are derived from the "Parser/Python.asdl" file, which is
   reproduced above.  They are defined in the "_ast" C module and re-
   exported in "ast".

   抽象文法中為每個左側符號定義了一個類別（例如 "ast.stmt" 或
   "ast.expr"）。此外，也為每個右側的建構函式 (constructor) 定義了一個
   類別；這些類別繼承自左側樹的類別。例如，"ast.BinOp" 繼承自
   "ast.expr"。對於具有替代方案（即為「和 (sums)」）的生產規則，左側類
   別是抽象的：僅有特定建構函式節點的實例會被建立。

   _fields

      每個具體類別都有一個屬性 "_fields"，它會給出所有子節點的名稱。

      具體類別的每個實例對於每個子節點都有一個屬性，其型別如文法中所定
      義。例如，"ast.BinOp" 實例具有型別為 "ast.expr" 的屬性 "left"。

      如果這些屬性在文法中被標記為可選（使用問號），則該值可能為
      "None"。如果屬性可以有零個或多個值（用星號標記），則這些值將表示
      為 Python 串列。使用 "compile()" 編譯 AST 時，所有可能的屬性都必
      須存在並且具有有效值。

   _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" 是原始文本跨度 (source text span) 的第一個和最後一
      個列號（1-indexed，因此第一列號是 1）以及 "col_offset" 和
      "end_col_offset" 是生成節點的第一個和最後一個標記對應的 UTF-8 位
      元組偏移量。會記錄 UTF-8 偏移量是因為剖析器 (parser) 內部使用
      UTF-8。

      請注意，編譯器並不需要結束位置，因此其為可選的。結束偏移量在最後
      一個符號*之後*，例如可以使用 "source_line[node.col_offset :
      node.end_col_offset]" 來取得單列運算式節點 (expression node) 的
      原始片段。

   "ast.T" 類別的建構函式按以下方式剖析其引數：

   * 如果有位置引數，則必須與 "T._fields" 中的項目一樣多；它們將被賦値
     為這些名稱的屬性。

   * 如果有關鍵字引數，它們會將相同名稱的屬性設定為給定值。

   例如，要建立並填充 (populate) "ast.UnaryOp" 節點，你可以使用：

      node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0),
                         lineno=0, col_offset=0)

   如果建構函式中省略了文法中可選的欄位，則它預設為 "None"。如果省略串
   列欄位，則預設為空串列。如果省略 "ast.expr_context" 型別的欄位，則
   預設為 "Load()"。如果省略任何其他欄位，則會引發
   "DeprecationWarning"，且 AST 節點將沒有此欄位。在 Python 3.15 中，
   這種情況會引發錯誤。

在 3.8 版的變更: "ast.Constant" 類別現在用於所有常數。

在 3.9 版的變更: 以它們的值表示簡單索引，擴充切片 (slice) 則以元組
(tuple) 表示。

在 3.13 版的變更: AST node constructors were changed to provide
sensible defaults for omitted fields: optional fields now default to
"None", list fields default to an empty list, and fields of type
"ast.expr_context" default to "Load()". Previously, omitted attributes
would not exist on constructed nodes (accessing them raised
"AttributeError").

在 3.14 版的變更: "AST" 節點的 "__repr__()" 輸出包含節點欄位的值。

自從版本 3.8 後不推薦使用，已從版本 3.14 中移除。: 過去的 Python 版本
提供了 AST 類別 "ast.Num"、"ast.Str"、"ast.Bytes"、"ast.NameConstant"
和 "ast.Ellipsis"，這些類別在 Python 3.8 中已被棄用。這些類別在 Python
3.14 中被移除，其功能已被 "ast.Constant" 取代。

在 3.9 版之後被棄用: 舊的類別 "ast.Index" 和 "ast.ExtSlice" 仍然可用，
但它們將在未來的 Python 版本中刪除。同時，實例化它們會回傳不同類別的實
例。

自從版本 3.13 後不推薦使用，已從版本 3.15 中移除。: Previous versions
of Python allowed the creation of AST nodes that were missing required
fields. Similarly, AST node constructors allowed arbitrary keyword
arguments that were set as attributes of the AST node, even if they
did not match any of the fields of the AST node. These cases now raise
a "TypeError".

自從版本 3.15 後不推薦使用，將會自版本 3.20 中移除。: In the grammar
above, the AST node classes that correspond to production rules with
variants (aka "sums") are abstract classes. Previous versions of
Python allowed for the creation of direct instances of these abstract
node classes. This behavior is deprecated and will be removed in
Python 3.20.

備註:

  這裡顯示的特定節點類別的描述最初是從出色的 Green Tree Snakes 專案和
  所有貢獻者那裡改編而來的。


根節點
------

class ast.Module(body, type_ignores)

   一個 Python 模組，與檔案輸入 一樣。由 "ast.parse()" 在預設的
   ""exec"" *mode* 下生成的節點型別。

   "body" 是模組的陳述式 的一個 "list"。

   "type_ignores" 是模組的忽略型別註解的 "list"；有關更多詳細資訊，請
   參閱 "ast.parse()"。

      >>> print(ast.dump(ast.parse('x = 1'), indent=4))
      Module(
          body=[
              Assign(
                  targets=[
                      Name(id='x', ctx=Store())],
                  value=Constant(value=1))])

class ast.Expression(body)

   單個 Python 運算式輸入。當 *mode* 是 ""eval"" 時節點型別由
   "ast.parse()" 生成。

   "body" 是單個節點，是運算式型別的其中之一。

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

class ast.Interactive(body)

   單個互動式輸入，和互動模式中所述的相似。當 *mode* 是 ""single"" 時
   節點型別由 "ast.parse()" 生成。

   "body" 是陳述式節點 (statement nodes) 的 "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 之前的 Python 版本不支援 **PEP
   484** 註釋。當 *mode* 是 ""func_type"" 時節點型別由 "ast.parse()"
   生成。

   這種型別的註解看起來像這樣：

      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'),
              Name(id='str')],
          returns=Subscript(
              value=Name(id='List'),
              slice=Name(id='int')))

   在 3.8 版被加入.


文本 (Literals)
---------------

class ast.Constant(value, kind)

   一個常數值。"Constant" 文本的 "value" 屬性包含它所代表的 Python 物
   件。表示的值可以是 "str"、"bytes"、"int"、"float"、"complex" 和
   "bool" 的實例，以及常數 "None" 和 "Ellipsis"。

   The "kind" attribute is an optional string. For string literals
   with a "u" prefix, "kind" is set to "'u'". For all other constants,
   "kind" is "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)

   表示 f 字串 (f-string) 中的單個格式化欄位的節點。如果字串包含單個格
   式欄位並且沒有其他內容，則可以隔離 (isolate) 該節點，否則它將出現在
   "JoinedStr" 中。

   * "value" 為任何運算式節點（例如文字、變數或函式呼叫）。

   * "conversion" 是一個整數：

     * -1: 無格式化

     * 97 ("ord('a')")："！a" "ASCII" 格式化

     * 114 ("ord('r')")："!r" "repr()" 格式化

     * 115 ("ord('s')")："!s" "string" 格式化

   * "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'),
                      conversion=-1),
                  Constant(value=') is '),
                  FormattedValue(
                      value=Call(
                          func=Name(id='sin'),
                          args=[
                              Name(id='a')]),
                      conversion=-1,
                      format_spec=JoinedStr(
                          values=[
                              Constant(value='.3')]))]))

class ast.TemplateStr(values, /)

   在 3.14 版被加入.

   表示模板字串字面值的節點，由一系列 "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'),
                      str='name',
                      conversion=-1),
                  Constant(value=' finished '),
                  Interpolation(
                      value=Name(id='place'),
                      str='place',
                      conversion=-1,
                      format_spec=JoinedStr(
                          values=[
                              Constant(value='ordinal')]))]))

class ast.Interpolation(value, str, conversion, format_spec=None)

   在 3.14 版被加入.

   表示模板字串字面值中單一插值欄位的節點。

   * "value" 為任何運算式節點（例如文字、變數或函式呼叫）。這和
     "FormattedValue.value" 的意思相同。

   * "str" 是一個包含插值運算式文字的常數。

     如果 "str" 被設為 "None"，則在呼叫 "ast.unparse()" 時會使用
     "value" 來產生程式碼。這不再保證產生的程式碼與原始程式碼相同，且
     適用於程式碼產生。

   * "conversion" 是一個整數：

     * -1：無規範

     * 97 ("ord('a')")："!a" "ASCII" 轉換

     * 114 ("ord('r')")："!r" "repr()" 轉換

     * 115 ("ord('s')")："!s" "string" 轉換

     這與 "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)=something" ），則 "ctx" 是 "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)]))
      >>> 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)]))

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)

   一個字典 (dictionary)。"keys" 和 "values" 分別按匹配順序保存表示鍵
   和值的節點串列（為呼叫 "dictionary.keys()" 和 "dictionary.values()"
   時將回傳的內容）。

   當使用字典文本進行字典解包 (unpack) 時，要擴充的運算式位於 "values"
   串列中，在 "keys" 中的相應位置有一個 "None"。

      >>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4))
      Expression(
          body=Dict(
              keys=[
                  Constant(value='a'),
                  None],
              values=[
                  Constant(value=1),
                  Name(id='d')]))


變數
----

class ast.Name(id, ctx)

   一個變數名稱。"id" 將名稱以字串形式保存，且 "ctx" 是以下型別之一。

class ast.Load
class ast.Store
class ast.Del

   變數參照可用於載入變數的值、為其分配新值或刪除它。變數參照被賦予情
   境 (context) 來區分這些情況。

      >>> print(ast.dump(ast.parse('a'), indent=4))
      Module(
          body=[
              Expr(
                  value=Name(id='a'))])

      >>> 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" 節點。在
   使用 "*args" 建置 "Call" 節點時必須使用此型別。

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


運算式
------

class ast.Expr(value)

   當運算式（例如函式呼叫）本身作為陳述式出現且未使用或儲存其回傳值時
   ，它將被包裝在此容器中。"value" 保存此區段 (section) 中的一個其他節
   點："Constant"、"Name"、"Lambda"、"Yield" 或 "YieldFrom"

      >>> print(ast.dump(ast.parse('-a'), indent=4))
      Module(
          body=[
              Expr(
                  value=UnaryOp(
                      op=USub(),
                      operand=Name(id='a')))])

class ast.UnaryOp(op, operand)

   一元運算 (unary operation)。"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')))

class ast.BinOp(left, op, right)

   二元運算 (binary operation)（如加法或除法）。 "op" 是運算子、"left"
   和 "right" 是任意運算式節點。

      >>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4))
      Expression(
          body=BinOp(
              left=Name(id='x'),
              op=Add(),
              right=Name(id='y')))

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

   二元運算子 token。

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'),
                  Name(id='y')]))

class ast.And
class ast.Or

   布林運算子 token。

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'),
                  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

   比較運算子 token。

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'),
              args=[
                  Name(id='a'),
                  Starred(
                      value=Name(id='d'))],
              keywords=[
                  keyword(
                      arg='b',
                      value=Name(id='c')),
                  keyword(
                      value=Name(id='e'))]))

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'),
              body=Name(id='a'),
              orelse=Name(id='c')))

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'),
              attr='colour'))

class ast.NamedExpr(target, value)

   一個附名運算式 (named expression)。該 AST 節點由賦值運算式運算子（
   也稱為海象運算子）產生。相對於 "Assign" 節點之第一個引數可為多個節
   點，在這種情況下 "target" 和 "value" 都必須是單個節點。

      >>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4))
      Expression(
          body=NamedExpr(
              target=Name(id='x', ctx=Store()),
              value=Constant(value=4)))

   在 3.8 版被加入.


下標 (Subscripting)
~~~~~~~~~~~~~~~~~~~

class ast.Subscript(value, slice, ctx)

   一個下標，例如 "l[1]"。"value" 是下標物件（通常是序列或對映）。
   "slice" 是索引、切片或鍵。它可以是一個 "Tuple" 並包含一個 "Slice"。
   根據下標執行的操作不同，"ctx" 可以是 "Load"、"Store" 或 "Del"。

      >>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4))
      Expression(
          body=Subscript(
              value=Name(id='l'),
              slice=Tuple(
                  elts=[
                      Slice(
                          lower=Constant(value=1),
                          upper=Constant(value=2)),
                      Constant(value=3)])))

class ast.Slice(lower, upper, step)

   常規切片（形式為 "lower:upper" 或 "lower:upper:step"）。只能直接或
   者或者作為 "Tuple" 的元素出現在 "Subscript" 的 *slice* 欄位內。

      >>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4))
      Expression(
          body=Subscript(
              value=Name(id='l'),
              slice=Slice(
                  lower=Constant(value=1),
                  upper=Constant(value=2))))


綜合運算式 (comprehensions)
~~~~~~~~~~~~~~~~~~~~~~~~~~~

class ast.ListComp(elt, generators)
class ast.SetComp(elt, generators)
class ast.GeneratorExp(elt, generators)
class ast.DictComp(key, value, generators)

   串列和集合綜合運算、生成器運算式和字典綜合運算。"elt"（或 "key" 和
   "value"）是單個節點，表示各個項目會被求值 (evaluate) 的部分。

   "generators" 是一個 "comprehension" 節點的串列。

      >>> print(ast.dump(
      ...     ast.parse('[x for x in numbers]', mode='eval'),
      ...     indent=4,
      ... ))
      Expression(
          body=ListComp(
              elt=Name(id='x'),
              generators=[
                  comprehension(
                      target=Name(id='x', ctx=Store()),
                      iter=Name(id='numbers'),
                      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'),
              value=BinOp(
                  left=Name(id='x'),
                  op=Pow(),
                  right=Constant(value=2)),
              generators=[
                  comprehension(
                      target=Name(id='x', ctx=Store()),
                      iter=Name(id='numbers'),
                      is_async=0)]))
      >>> print(ast.dump(
      ...     ast.parse('{x for x in numbers}', mode='eval'),
      ...     indent=4,
      ... ))
      Expression(
          body=SetComp(
              elt=Name(id='x'),
              generators=[
                  comprehension(
                      target=Name(id='x', ctx=Store()),
                      iter=Name(id='numbers'),
                      is_async=0)]))

class ast.comprehension(target, iter, ifs, is_async)

   綜合運算中的一個 "for" 子句。"target" 是用於每個元素的參照 - 通常是
   "Name" 或 "Tuple" 節點。"iter" 是要疊代的物件。"ifs" 是測試運算式的
   串列：每個 "for" 子句可以有多個 "ifs"。

   "is_async" 表示綜合運算式是非同步的（使用 "async for" 而不是 "for"
   ）。該值為整數（0 或 1）。

      >>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'),
      ...                indent=4)) # Multiple comprehensions in one.
      Expression(
          body=ListComp(
              elt=Call(
                  func=Name(id='ord'),
                  args=[
                      Name(id='c')]),
              generators=[
                  comprehension(
                      target=Name(id='line', ctx=Store()),
                      iter=Name(id='file'),
                      is_async=0),
                  comprehension(
                      target=Name(id='c', ctx=Store()),
                      iter=Name(id='line'),
                      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'),
                  op=Pow(),
                  right=Constant(value=2)),
              generators=[
                  comprehension(
                      target=Name(id='n', ctx=Store()),
                      iter=Name(id='it'),
                      ifs=[
                          Compare(
                              left=Name(id='n'),
                              ops=[
                                  Gt()],
                              comparators=[
                                  Constant(value=5)]),
                          Compare(
                              left=Name(id='n'),
                              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'),
              generators=[
                  comprehension(
                      target=Name(id='i', ctx=Store()),
                      iter=Name(id='soc'),
                      is_async=1)]))


陳述式
------

class ast.Assign(targets, value, type_comment)

   一個賦值。"targets" 是節點串列，"value" 是單個節點。

   "targets" 中的多個節點表示為每個節點分配相同的值。解包是透過在
   "targets" 中放置一個 "Tuple" 或 "List" 來表示的。

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

class ast.AnnAssign(target, annotation, value, simple)

   帶有型別註釋的賦值。"target" 是單個節點，可以是 "Name"、"Attribute"
   或 "Subscript"。"annotation" 是註釋，例如 "Constant" 或 "Name" 節點
   。"value" 是單個可選節點。

   "simple" 總會是 0（表示一個「複雜」目標）或 1（表示一個「簡單」目標
   ）。一個「簡單」目標僅包含一個 "Name" 節點，且不出現在括號之間；所
   有其他目標都被視為是複雜的。只有簡單目標會出現在模組和類別的
   "__annotations__" 字典中。

      >>> print(ast.dump(ast.parse('c: int'), indent=4))
      Module(
          body=[
              AnnAssign(
                  target=Name(id='c', ctx=Store()),
                  annotation=Name(id='int'),
                  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'),
                  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'),
                      attr='b',
                      ctx=Store()),
                  annotation=Name(id='int'),
                  simple=0)])

      >>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation
      Module(
          body=[
              AnnAssign(
                  target=Subscript(
                      value=Name(id='a'),
                      slice=Constant(value=1),
                      ctx=Store()),
                  annotation=Name(id='int'),
                  simple=0)])

class ast.AugAssign(target, op, value)

   增加賦值 (augmented assignment)，例如 "a += 1"。在下面的範例中，
   "target" 是 "x" 的 "Name" 節點（帶有 "Store" 情境），"op" 是 "Add"
   ，"value" 是一個值為 1 的 "Constant"。

   與 "Assign" 的目標不同，"target" 屬性不能屬於 "Tuple" 或 "List" 類
   別。

      >>> 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"，若是獨立的 "raise" 則為 "None"。"cause" 是 "raise x from y"
   中的可選部分 "y"。

      >>> print(ast.dump(ast.parse('raise x from y'), indent=4))
      Module(
          body=[
              Raise(
                  exc=Name(id='x'),
                  cause=Name(id='y'))])

class ast.Assert(test, msg)

   一個斷言 (assertion)。"test" 保存條件，例如 "Compare" 節點。"msg"
   保存失敗訊息。

      >>> print(ast.dump(ast.parse('assert x,y'), indent=4))
      Module(
          body=[
              Assert(
                  test=Name(id='x'),
                  msg=Name(id='y'))])

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" 陳述式建立的型別別名 (type alias)。"name" 是別名的名稱
   、"type_params" 是型別參數 (type parameter) 的串列、"value" 是型別
   別名的值。

      >>> print(ast.dump(ast.parse('type Alias = int'), indent=4))
      Module(
          body=[
              TypeAlias(
                  name=Name(id='Alias', ctx=Store()),
                  value=Name(id='int'))])

   在 3.12 版被加入.

其他僅適用於函式或迴圈內部的陳述式將在其他部分中描述。


引入 (imports)
~~~~~~~~~~~~~~

class ast.Import(names)

   一個 import 陳述式。"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')],
                  is_lazy=0)])

class ast.ImportFrom(module, names, level)

   代表 "from x import y"。"module" 是 'from' 名稱的原始字串，前面沒有
   任何的點 (dot)，或者對於諸如 "from . import foo" 之類的陳述式則為
   "None"。"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,
                  is_lazy=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,
                  is_lazy=0)])


流程控制
--------

備註:

  諸如 "else" 之類的可選子句如果不存在，則將被儲存為空串列。

class ast.If(test, body, orelse)

   一個 "if" 陳述式。"test" 保存單個節點，例如 "Compare" 節點。"body"
   和 "orelse" 各自保存一個節點串列。

   "elif" 子句在 AST 中沒有特殊表示，而是在前一個子句的 "orelse" 部分
   中作為額外的 "If" 節點出現。

      >>> print(ast.dump(ast.parse("""
      ... if x:
      ...    ...
      ... elif y:
      ...    ...
      ... else:
      ...    ...
      ... """), indent=4))
      Module(
          body=[
              If(
                  test=Name(id='x'),
                  body=[
                      Expr(
                          value=Constant(value=Ellipsis))],
                  orelse=[
                      If(
                          test=Name(id='y'),
                          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'),
                  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'),
                  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'),
                  body=[
                      If(
                          test=Compare(
                              left=Name(id='a'),
                              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'),
                          body=[
                              Expr(
                                  value=Constant(value=Ellipsis))]),
                      ExceptHandler(
                          type=Name(id='OtherException'),
                          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" 相同，但是
   "handlers" 中的 "ExceptHandler" 節點被直譯 (interpret) 為 "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'),
                          body=[
                              Expr(
                                  value=Constant(value=Ellipsis))])])])

   在 3.11 版被加入.

class ast.ExceptHandler(type, name, body)

   單個 "except" 子句。"type" 是會被匹配的例外型別，通常是一個 "Name"
   節點（或者 "None" 表示會捕捉到所有例外的 "except:" 子句）。"name"
   是用於保存例外的名稱之原始字串，如果子句沒有 "as foo" ，則為 "None"
   。"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'),
                              op=Add(),
                              right=Constant(value=1)))],
                  handlers=[
                      ExceptHandler(
                          type=Name(id='TypeError'),
                          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" 是 "as foo" 部分的 "Name"、
   "Tuple" 或 "List"，或者如果不使用則為 "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'),
                          optional_vars=Name(id='b', ctx=Store())),
                      withitem(
                          context_expr=Name(id='c'),
                          optional_vars=Name(id='d', ctx=Store()))],
                  body=[
                      Expr(
                          value=Call(
                              func=Name(id='something'),
                              args=[
                                  Name(id='b'),
                                  Name(id='d')]))])])


模式匹配 (pattern matching)
---------------------------

class ast.Match(subject, cases)

   一個 "match" 陳述式。"subject" 保存匹配的主題（與案例匹配的物件），
   "cases" 包含具有不同案例的 "match_case" 節點的可疊代物件。

   在 3.10 版被加入.

class ast.match_case(pattern, guard, body)

   "match" 陳述式中的單個案例模式。"pattern" 包含主題將與之匹配的匹配
   模式。請注意，為模式生成的 "AST" 節點與為運算式生成的節點不同，即使
   它們共享相同的語法。

   "guard" 屬性包含一個運算式，如果模式與主題匹配，則將對該運算式求值
   。

   "body" 包含一個節點串列，如果模式匹配並且為防護運算式 (guard
   expression) 的求值 (evaluate) 結果為真，則會執行該節點串列。

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

   在 3.10 版被加入.

class ast.MatchSingleton(value)

   按識別性 (identity) 進行比較的匹配文本模式。"value" 是要與 "None"、
   "True" 或 "False" 進行比較的單例 (singleton)。如果匹配主題是給定的
   常數，則此模式成功。

      >>> print(ast.dump(ast.parse("""
      ... match x:
      ...     case None:
      ...         ...
      ... """), indent=4))
      Module(
          body=[
              Match(
                  subject=Name(id='x'),
                  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'),
                  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'),
                  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" 是一個可選名稱，可以指定它來捕獲剩餘的對映元素。允許
   的鍵運算式受到匹配陳述式文件中所述的限制。

   如果主題是對映，所有求值出的鍵運算式都存在於對映中，並且與每個鍵對
   應的值與相應的子模式匹配，則此模式成功。如果 "rest" 不是 "None"，則
   如果整體對映模式成功，則包含其餘對映元素的字典將綁定到該名稱。

      >>> print(ast.dump(ast.parse("""
      ... match x:
      ...     case {1: _, 2: _}:
      ...         ...
      ...     case {**rest}:
      ...         ...
      ... """), indent=4))
      Module(
          body=[
              Match(
                  subject=Name(id='x'),
                  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" 是一個給定要匹配的名義類別 (nominal class) 的運
   算式。"patterns" 是要與類別定義的模式匹配屬性序列進行匹配的模式節點
   序列。"kwd_attrs" 是要匹配的附加屬性序列（在類別模式中指定為關鍵字
   引數），"kwd_patterns" 是相應的模式（在類別模式中指定為關鍵字的值）
   。

   如果主題是指定類別的實例，所有位置模式都與相應的類別定義屬性匹配，
   並且任何指定的關鍵字屬性與其相應模式匹配，則此模式成功。

   注意：類別可以定義一個回傳 self 的特性 (property)，以便將模式節點與
   正在匹配的實例進行匹配。一些內建型別也以這種方式匹配，如同匹配陳述
   式文件中所述。

      >>> 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'),
                  cases=[
                      match_case(
                          pattern=MatchClass(
                              cls=Name(id='Point2D'),
                              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'),
                              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 pattern)。"pattern" 包含主題將與之匹配的匹配模式。
   如果模式為 "None"，則該節點代表捕獲模式（即裸名 (bare name)）並且始
   終會成功。

   "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'),
                  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 模式 (or-pattern)」。 or 模式依次將其每個子模式與主題進
   行匹配，直到成功為止，然後 or 模式就會被認為是成功的。如果沒有一個
   子模式成功，則 or 模式將失敗。 "patterns" 屬性包含將與主題進行匹配
   的匹配模式節點串列。

      >>> print(ast.dump(ast.parse("""
      ... match x:
      ...     case [x] | (y):
      ...         ...
      ... """), indent=4))
      Module(
          body=[
              Match(
                  subject=Name(id='x'),
                  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)

   位於 *lineno* 的 "# type: ignore" 註解。*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'),
                  value=Constant(value=1),
                  simple=1)],
          type_ignores=[
              TypeIgnore(lineno=1, tag='[assignment]')])

   備註:

     當 *type_comments* 參數設為 "False"（預設值）時，不會產生
     "TypeIgnore" 節點。更多細節請參閱 "ast.parse()"。

   在 3.8 版被加入.


型別參數 (type parameters)
--------------------------

型別參數可以存在於類別、函式和型別別名上。

class ast.TypeVar(name, bound, default_value)

   一個 "typing.TypeVar"。"name" 是型別變數的名稱。"bound" 是（如果有
   存在的）界限 (bound) 或約束 (constraint)。如果 "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'),
                          default_value=Name(id='bool'))],
                  value=Subscript(
                      value=Name(id='list'),
                      slice=Name(id='T')))])

   在 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'),
                                  Name(id='str')]))],
                  value=Subscript(
                      value=Name(id='Callable'),
                      slice=Tuple(
                          elts=[
                              Name(id='P'),
                              Name(id='int')])))])

   在 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())],
                  value=Subscript(
                      value=Name(id='tuple'),
                      slice=Tuple(
                          elts=[
                              Starred(
                                  value=Name(id='Ts'))])))])

   在 3.12 版被加入.

   在 3.13 版的變更: 新增 *default_value* 參數。


函式和類別定義
--------------

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

   一個函式定義。

   * "name" 是函式名稱的原始字串。

   * "args" 是一個 "arguments" 節點。

   * "body" 是函式內節點的串列。

   * "decorator_list" 是要應用的裝飾器串列，在最外層者會被儲存在首位（
     即串列中首位將會是最後一個被應用的那個）。

   * "returns" 是回傳註釋。

   * "type_params" 是型別參數的串列。

   type_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'),
                      Name(id='decorator2')],
                  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')))])

      >>> print(ast.dump(ast.parse('yield from x'), indent=4))
      Module(
          body=[
              Expr(
                  value=YieldFrom(
                      value=Name(id='x')))])

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** 所述，其他關鍵字將被傳遞到 metaclass。

   * "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'),
                      Name(id='base2')],
                  keywords=[
                      keyword(
                          arg='metaclass',
                          value=Name(id='meta'))],
                  body=[
                      Pass()],
                  decorator_list=[
                      Name(id='decorator1'),
                      Name(id='decorator2')])])

   在 3.12 版的變更: 新增了 "type_params"。


async 和 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" 主體 (body) 中有效。

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

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" 模組還定義了這些用於遍歷 (traverse) 抽象語法樹
的實用函式和類別：

ast.parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None, optimize=-1, module=None)

   Parse the source into an AST node.  Equivalent to "compile(source,
   filename, mode, flags=FLAGS_VALUE, optimize=optimize,
   module=module)", where "FLAGS_VALUE" is "ast.PyCF_ONLY_AST" if
   "optimize <= 0" and "ast.PyCF_OPTIMIZED_AST" otherwise.

   如果給定 "type_comments=True"，剖析器將被修改為檢查並回傳 **PEP
   484** 和 **PEP 526** 指定的型別註釋。這相當於將
   "ast.PyCF_TYPE_COMMENTS" 新增到傳遞給 "compile()" 的旗標中。這將報
   告錯誤型別註釋的語法錯誤。如果沒有此旗標，型別註釋將被忽略，並且所
   選 AST 節點上的 "type_comment" 欄位將始終為 "None"。此外，"# type:
   ignore" 註釋的位置將作為 "Module" 的 "type_ignores" 屬性回傳（否則
   它始終是一個空串列）。

   此外，如果 "mode" 是 "'func_type'"，則輸入語法將會依據 **PEP 484**
   「簽名型別註解 (signature type comments)」而被修改，例如 "(str,
   int) -> List[str]"。

   將 "feature_version" 設定為元組 "(major, minor)" 將「盡可能」嘗試使
   用該 Python 版本的文法進行剖析。目前 "major" 必須等於 "3"。例如，設
   定 "feature_version=(3, 9)" 將嘗試禁止剖析 "match" 陳述式。目前
   "major" 必須為 "3"、支援的最低版本為 "(3, 7)"（這在未來的 Python 版
   本中可能會增加）；最高的是 "sys.version_info[0:2]"。「盡可能」嘗試
   意味著不能保證剖析（或剖析的成功）與在與 "feature_version" 對應的
   Python 版本上運行時相同。

   如果來源包含 null 字元 ("\0")，則會引發 "ValueError"。

   警告:

     請注意，成功將原始碼剖析為 AST 物件並不能保證提供的原始碼是可以執
     行的有效 Python 程式碼，因為編譯步驟可能會引發進一步的
     "SyntaxError" 例外。例如，原始的 "return 42" 為 return 陳述式生成
     一個有效的 AST 節點，但它不能單獨編譯（它需要位於函式節點內）。特
     別是 "ast.parse()" 不會執行任何範圍檢查，而編譯步驟才會執行此操作
     。

   警告:

     由於 Python AST 編譯器中的堆疊 (stack) 深度限制，太大或太複雜的字
     串可能會導致 Python 直譯器崩潰。

   在 3.8 版的變更: 新增 "type_comments"、"mode='func_type'" 與
   "feature_version"。

   在 3.13 版的變更: "feature_version" 的最低支援版本現在是 "(3, 7)"。
   新增了 "optimize" 引數。

   在 3.15 版被加入: Added the *module* parameter.

ast.unparse(ast_obj)

   反剖析 "ast.AST" 物件並生成一個帶有程式碼的字串，如果使用
   "ast.parse()" 剖析回來，該程式碼將生成等效的 "ast.AST" 物件。

   警告:

     生成的程式碼字串不一定等於生成 "ast.AST" 物件的原始程式碼（沒有任
     何編譯器最佳化，例如常數元組/凍結集合）。

   警告:

     嘗試剖析高度複雜的運算式會導致 "RecursionError"。

   在 3.9 版被加入.

ast.literal_eval(node_or_string)

   為僅包含 Python 文本或容器之顯示的運算式節點或字串來求值。提供的字
   串或節點只能包含以下 Python 文本結構：字串、位元組、數字、元組、串
   列、字典、集合、布林值、"None" 和 "Ellipsis"。

   這可用於為包含 Python 值的字串求值，而無需自己剖析這些值。它無法計
   算任意複雜的運算式，例如涉及運算子或索引。

   該函式過去被記錄為「安全」，但沒有定義其含義，這有點誤導讀者，它是
   特別設計為不去執行 Python 程式碼，與更通用的 "eval()" 不同。沒有命
   名空間、沒有名稱查找、也沒有呼叫的能力。但它也不能免受攻擊：相對較
   小的輸入可能會導致記憶體耗盡或 C 堆疊耗盡，從而導致行程崩潰。某些輸
   入也可能會出現 CPU 消耗過多而導致拒絕服務的情況。因此不建議在不受信
   任的資料上呼叫它。

   警告:

     由於 Python AST 編譯器的堆疊深度限制，Python 直譯器可能會崩潰。它
     可能會引發 "ValueError"、"TypeError"、"SyntaxError"、
     "MemoryError" 和 "RecursionError"，具體取決於格式錯誤的輸入。

   在 3.2 版的變更: 現在允許位元組和集合文本 (set literal)。

   在 3.9 版的變更: 現在支援使用 "'set()'" 建立空集合。

   在 3.10 版的變更: 對於字串輸入，前導空格和定位字元 (tab) 現在已被去
   除。

ast.get_docstring(node, clean=True)

   回傳給定 *node* 的文件字串 (docstring)（必須是 "FunctionDef"、
   "AsyncFunctionDef"、"ClassDef" 或 "Module" 節點）或如果它沒有文件字
   串則為 "None"。如果 *clean* 為 true，則使用 "inspect.cleandoc()" 清
   理文件字串的縮排。

   在 3.5 版的變更: 目前已支援 "AsyncFunctionDef"。

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

   取得生成 *node* 的 *source* 的原始碼片段。如果某些位置資訊（
   "lineno"、"end_lineno"、"col_offset" 或 "end_col_offset"）遺漏，則
   回傳 "None"。

   如果 *padded* 為 "True"，則多列陳述式的第一列將用空格填充 (padded)
   以匹配其原始位置。

   在 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* 上存在的 "node._fields" 中的每個欄位生成一個 "(fieldname,
   value)" 元組。

ast.iter_child_nodes(node)

   生成 *node* 的所有直接子節點，即作為節點的所有欄位以及作為節點串列
   欄位的所有項目。

ast.walk(node)

   遞迴地生成樹中從 *node* 開始的所有後代節點（包括 *node* 本身），不
   按指定順序。如果你只想就地修改節點而不關心情境，這非常有用。

class ast.NodeVisitor

   節點瀏覽者基底類別，它遍歷抽象語法樹並為找到的每個節點呼叫瀏覽者函
   式。該函式可能會回傳一個由 "visit()" 方法轉發的值。

   這個類別應該被子類別化，子類別新增瀏覽者方法。

   visit(node)

      瀏覽一個節點。預設實作呼叫名為 "self.visit_*classname*" 的方法，
      其中 *classname* 是節點類別的名稱，或者在該方法不存在時呼叫
      "generic_visit()"。

   generic_visit(node)

      該瀏覽者對該節點的所有子節點呼叫 "visit()"。

      請注意，除非瀏覽者呼叫 "generic_visit()" 或瀏覽它們本身，否則不
      會瀏覽具有自訂瀏覽者方法的節點之子節點。

   visit_Constant(node)

      處理所有常數節點。

   如果你想在遍歷期間將變更應用 (apply) 於節點，請不要使用
   "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'),
                  slice=Constant(value=node.id),
                  ctx=node.ctx
              )

   請記住，如果你正在操作的節點有子節點，你必須自己轉換子節點或先呼叫
   該節點的 "generic_visit()" 方法。

   對於屬於陳述式總集 (collection) 一部分的節點（適用於所有陳述式節點
   ），瀏覽者還可以回傳節點串列，而不僅僅是單個節點。

   如果 "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, *, color=False, indent=None, show_empty=False)

   回傳 *node* 中樹的格式化傾印 (formatted dump)，這主要用於除錯。如果
   *annotate_fields* 為 true（為預設值），則回傳的字串將顯示欄位的名稱
   和值。如果 *annotate_fields* 為 false，則透過省略明確的欄位名稱，結
   果字串將更加縮減簡潔。預設情況下，不會傾印列號和行偏移量等屬性。如
   果需要，可以設定 *include_attributes* 為 true。

   If *color* is "True", the returned string is syntax highlighted
   using ANSI escape sequences. If "False" (the default), colored
   output is always disabled.

   如果 *indent* 是非負整數或字串，那麼樹將使用該縮排級別來做漂亮印出
   (pretty-print)。縮排級別 0、負數或 """" 只會插入換列符號 (newlines)
   。"None"（預設值）代表選擇單列表示。使用正整數縮排可以在每個級別縮
   排相同數量的空格。如果 *indent* 是一個字串（例如 ""\t""），則該字串
   用於縮排每個級別。

   If *show_empty* is false (the default), optional empty lists and
   "Load()" values will be omitted from the output. Optional "None"
   values are always omitted.

      >>> tree = ast.parse('print(None)', '?', 'eval')
      >>> print(ast.dump(tree, indent=4))
      Expression(
          body=Call(
              func=Name(id='print'),
              args=[
                  Constant(value=None)]))
      >>> print(ast.dump(tree, indent=4, show_empty=True))
      Expression(
          body=Call(
              func=Name(id='print', ctx=Load()),
              args=[
                  Constant(value=None)],
              keywords=[]))

   在 3.9 版的變更: 新增 *indent* 選項。

   在 3.13 版的變更: 新增 *show_empty* 選項。

   在 3.15 版的變更: Omit optional "Load()" values by default.

   在 3.15 版的變更: Added the *color* parameter.

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 會根據 "compile()" 或 "ast.parse()" 中的 *optimize* 引數
   進行最佳化。

   在 3.13 版被加入.

ast.PyCF_TYPE_COMMENTS

   啟用對 **PEP 484** 和 **PEP 526** 樣式型別註釋的支援 ("# type:
   <type>", "# type: ignore <stuff>")。

   在 3.8 版被加入.


命令列用法
==========

在 3.9 版被加入.

在 3.15 版的變更: The output is now syntax highlighted by default.
This can be controlled using environment variables.

"ast" 模組可以作為腳本從命令列執行，可以像這樣簡單地做到：

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

以下選項可被接受：

-h, --help

   顯示幫助訊息並退出。

-m <mode>
--mode <mode>

   指定必須編譯哪種類型的程式碼，像是 "parse()" 中的 *mode* 引數。

--no-type-comments

   不要剖析型別註解。

-a, --include-attributes

   包括列號和行偏移量等屬性。

-i <indent>
--indent <indent>

   AST 中節點的縮進（空格數）。

--feature-version <version>

   以 3.x 格式表示的 Python 版本（例如 3.10）。預設為直譯器的目前版本
   。

   在 3.14 版被加入.

-O <level>
--optimize <level>

   剖析器的最佳化層級。預設為不進行最佳化。

   在 3.14 版被加入.

--show-empty

   顯示空串列和值為 "None" 的欄位。預設為不顯示空物件。

   在 3.14 版被加入.

如果指定了 "infile"，則其內容將被剖析為 AST 並傾印 (dump) 到 stdout。
否則會從 stdin 讀取內容。

也參考:

  Green Tree Snakes 是一個外部文件資源，提供了有關使用 Python AST 的詳
  細資訊。

  ASTTokens 使用生成它們的原始碼中的標記和文本的位置來註釋 Python AST
  。這對於進行原始碼轉換的工具很有幫助。

  leoAst.py 透過在 token 和 ast 節點之間插入雙向鏈結，統一了 python 程
  式的基於 token 和基於剖析樹的視圖。

  LibCST 將程式碼剖析為具體語法樹 (Concrete Syntax Tree)，看起來像 ast
  樹並保留所有格式詳細資訊。它對於建置自動重構 (codemod) 應用程式和
  linter 非常有用。

  Parso 是一個 Python 剖析器，支援不同 Python 版本的錯誤復原和往返剖析
  。Parso 還能夠列出 Python 檔案中的多個語法錯誤。
