0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PythonのAST(Python抽象構文木)の解析結果を分かり易く可視化するコードの試作

Last updated at Posted at 2023-08-05

はじめに

Pythonのコードを解析するツール(Python標準ライブラリにあるAST)を使用して、Pythonのコード(構文構造)を解析した結果の内容を、Pythonの元コードと合わせて分かり易くまとめてテキスト形式で出力します。

AST

Pythonのコードを解析して、構文に分解、結果をツリー状の辞書(dict)として得られる、AST(Python抽象構文木)が、Python標準ライブラリの中にあります。

ASTコード解析結果の辞書(dict)は、例えば下記の図のようなものになります。

ASTコード解析結果例:
image.png

辞書(dict)の形式では、全情報が羅列され、構造が見えにくく、元のコードとの対応も分かりにくいものになります。

結果を分かり易くまとめて出力

このASTコード解析結果の辞書(dict)形式のままでは、結果が見にくいので、下図のようにPythonの元コードと併記して構造を可視化し、分かり易くまとめてテキスト形式で出力するコードを、ここで試作します。

試作コードの出力結果例: (下図)
image.png

使用方法 (呼出し方法)

試作したコードは、後述の「コード全体」章にあります。

この試作コードを用いて、ASTコード解析結果を分かり易くまとめて出力するには、

print_ast("sample_code.py")

上記のように、print_ast関数を呼び出すのみになります。

引数に解析したいPythonコードのファイル(.py)へのパスを指定します。
実行すると、ASTコード解析結果を分かり易くまとめたテキスト形式のファイルが出力されます。

処理方法

大きく3つの部分からなり、

  • class AstResultPrinter
  • class AstAndPyCodeZipper
  • def print_ast

それぞれ、

  • 実体のメインは、AstResultPrinterクラス、
  • AstAndPyCodeZipperクラスは、ASTコード解析結果を、Pythonの元コードと併記した形で出力するもの、
  • print_ast関数は、AstResultPrinterクラスを簡単に呼び出せるようにした関数(ヘルパー関数)、

になります。

ASTコード解析結果から得られる各要素のNodeオブジェクトを、辞書(dict)形式の文字列に直して(str(node_i.__dict__))、表示が不要なものを除去するテキスト置換を繰り返し行う処理がメインになります。

これに合わせて、各要素のNodeオブジェクトに対応する、Pythonの元コードを抽出し(class AstAndPyCodeZipper)、ASTコード解析結果と元コードを併記して分かり易くまとめてテキスト形式で出力します。

コードの構成

試作したコード全体の構成は、

コードの構成
import:
-------
グローバル域でimport:
import ast, re
import pathlib

ローカル域でimport:
なし

コード構造:
-----------

# sec: main

def main(): # 実行切替用

def run__main1():
      ↓
    # sec: config
      ↓
    # sec: run

# sec: AST(Python抽象構文木)可視化

# ASTコード解析結果を分かり易くまとめてテキスト形式で出力、Pythonの元コードと合わせて併記
class AstResultPrinter:

    def print_ast(cls, 

        (内包関数)
        def print_node(node, lv=0):
              ↓
            # sec: 対応するpyコードを取得
              ↓
            # sec: 位置
              ↓
            # sec: 読込型・書込型
              ↓
            # sec: 置換 (表示が不要なものを除去)
              ↓
            # sec: 出力

# ASTのnodeが指し示す行位置に対応するpyコードを返す
class AstAndPyCodeZipper:

    def __init__(self, code):
          ↓
        # sec: config
          ↓
        # sec: inner state

            (内包関数)
            def get_next_py_code__non(self, *args, **kwargs): return ""

    # ASTのnodeが指し示す行位置に対応するpyコードを取得 (前回の書出し分は除く)
    def get_next_py_code(self, node, i_from=None, i_to=None):
          ↓
        # sec: pyコード
          ↓
        # sec: 整形

    # ASTのnodeが指し示す行位置に対応するpyコードを取得 (前回の書出し分は除く)
    def get_next_py_code__raw(self, node, i_from=None, i_to=None):
          ↓
        # sec: nodeの行位置
          ↓
        # sec: 対応するpyコード

# ASTコード解析結果を分かり易くまとめてテキスト形式で出力、Pythonの元コードと合わせて併記
def print_ast(
      ↓
    # sec: 引数チェック
      ↓
    # sec: main
          ↓
        # sec: AST解析
          ↓
        # sec: AST可視化

image.png

コード全体

試作したコード全体は、

run__print_AST.py
# -*- coding: utf-8 -*-

# AST(pyコード分析ツリー)内容を可視化する機能
# ASTコード解析結果を分かり易くまとめてテキスト形式で出力、Pythonの元コードと合わせて併記

import ast, re
import pathlib

# sec: main

def main(): # 実行切替用
    run__main1()

def run__main1():

    # sec: config
    
    path_py = "sample_code1.py"
    # path_py = "sample_code2__run__car_path_plan_simu.py"
    
    # sec: run
    
    print_ast(path_py)
    
# sec: AST(pyコード分析ツリー)可視化

# ASTコード解析結果を分かり易くまとめてテキスト形式で出力、Pythonの元コードと合わせて併記
class AstResultPrinter:

    re_key = re.compile(r"'(?P<n>[\d\w]+)':") # key名マッチ
    re_line_B = re.compile(r"lineno\: \d+[,}]\s*") # 行情報マッチ
    re_col_B = re.compile(r"col_offset\: \d+[,}]\s*") # 文字位置情報マッチ
    re_line_E = re.compile(r"end_lineno\: \d+[,}]\s*") # 行情報マッチ
    re_col_E = re.compile(r"end_col_offset\: \d+[,}]\s*") # 文字位置情報マッチ
    re_obj = re.compile(r"\<_?ast\.(?P<c>\w+) object at 0x[\d\w]+\>") # ASTクラス表記マッチ
    re_end1 = re.compile(r",\s*$") # 余分な末尾","マッチ
    re_end2 = re.compile(r"(?<=[^}])$") # "}"なしの末尾マッチ
    
    @classmethod
    def print_ast(cls, 
        node, # ASTコード解析結果のツリーオブジェクト(ast.parse(code)の結果を渡す)
        code = None, # pyソースコードのテキスト
        path_out = "print_ast.py"): # 出力ファイルへのパス
        
        pyco = AstAndPyCodeZipper(code) # 対応するpyコードを取得
        pyco.header = ">" + "=" * 60 + ":py\n"
        pyco.prefix = "{0:4d}|py: "
        pyco.footer = " " + "- " * 30 + ":ast\n"
        
        file = open(path_out, "w")
        
        def print_node(node, lv=0):
            
            for node_i in ast.iter_child_nodes(node): # 全てflat化して子node列挙
            
                if node_i.__class__.__name__ in ("Load", "Store"): # if: 内容無しクラス -> 飛ばす
                    continue
                
                # sec: 対応するpyコードを取得
                
                code_py = pyco.get_next_py_code(node_i) # NOTE: 後段でpyco.has_posを使う為、get_next_py_codeはそれ以前に呼出し
                if len(code_py) > 0:
                    file.write(code_py)
                
                # sec: 位置
                
                try:
                    i_line, i_col, has_pos = node_i.lineno - 1, node_i.col_offset - 1, True # 開始番号は1からの為
                except:
                    has_pos = False
                
                if has_pos:
                    text_no = "%4d:%2d|" % (i_line + 1, i_col + 1)
                else:
                    text_no = "       |"
                
                # sec: 読込型・書込型
                
                try:
                    text_ctx = node_i.ctx.__class__.__name__
                except:
                    text_ctx = ""
                if text_ctx == "Load": # if: 変数から読込型
                    text_rw = "R "
                elif text_ctx == "Store": # if: 変数へ書込型
                    text_rw = "W "
                else:
                    text_rw = "  "
                
                # sec: 置換 (表示が不要なものを除去)
                
                text_di = str(node_i.__dict__) # nodeのメンバ dictの文字列表記
                text_di = cls.re_key.sub(r"\g<n>:", text_di)
                text_di = cls.re_line_E.sub("", text_di) # 同じ文字列を含む為、re_line_Eから除去
                text_di = cls.re_col_E.sub("", text_di)
                text_di = cls.re_line_B.sub("", text_di) # 同じ文字列を含む為、後でre_line_Bを除去
                text_di = cls.re_col_B.sub("", text_di)
                text_di = cls.re_obj.sub(r"\g<c>", text_di)
                text_di = text_di.replace("ctx: Load, ", "")
                text_di = text_di.replace(", ctx: Load", "")
                text_di = text_di.replace("ctx: Store, ", "")
                text_di = text_di.replace(", ctx: Store", "")
                text_di = text_di.replace(", type_comment: None", "") # 変数の属性 型なし時は除去
                text_di = text_di.replace(", kind: None", "") # Constantの属性 種なし時は除去
                text_di = text_di.replace("posonlyargs: [], ", "") # argumentsの属性 空時は除去
                text_di = cls.re_end1.sub("", text_di)
                text_di = cls.re_end2.sub("}", text_di)
                
                # sec: 出力
                
                file.write("%s%s %s %s %s\n" % (text_no, text_rw, " " * lv * 4, node_i.__class__.__name__, text_di))
                
                print_node(node_i, lv + 1) # 再帰呼び出し
        
        print_node(node, lv=0)
        
        file.close()

# ASTのnodeが指し示す行位置に対応するpyコードを返す
class AstAndPyCodeZipper:
    # assume: コード上方から順番に処理され、get_next_py_codeが順次呼び出される想定
    
    def __init__(self, code):
        
        # sec: config
        
        self.header = ">" + "=" * 60 + ":py\n"
        self.prefix = "{0:4d}|py: " # {0:4d}等でpy行番号が入る
        self.footer = " " + "- " * 30 + ":ast\n"
        
        # sec: inner state
        
        if code is None: # if: 機能無効化
            def get_next_py_code__non(self, *args, **kwargs): return ""
            self.get_next_py_code = get_next_py_code__non
            return
        
        self.codes = code.split("\n")
        self.i_E_curr = -1
    
    # ASTのnodeが指し示す行位置に対応するpyコードを取得 (前回の書出し分は除く)
    def get_next_py_code(self, node, i_from=None, i_to=None):
        
        # sec: pyコード
        
        codes_py = self.get_next_py_code__raw(node, i_from, i_to)
        if len(codes_py) == 0: # if: pyコード無し
            return ""
        
        i_B_code = self.i_E_curr - len(codes_py) + 1 # pyコード先頭行番号
        
        # sec: 整形
        
        text_out = self.header
        
        for i_line, code_py in enumerate(codes_py):
            text_out += self.prefix.format(i_B_code + i_line + 1) + code_py + "\n"
        
        text_out += self.footer
        
        return text_out
    
    # ASTのnodeが指し示す行位置に対応するpyコードを取得 (前回の書出し分は除く)
    def get_next_py_code__raw(self, node, i_from=None, i_to=None):
        # assume: 後段処理の都合上、切り出し結果は行のリストで返す
        
        # sec: nodeの行位置
        
        try:
            i_line, has_pos = node.lineno - 1, True # 開始番号は1からの為
        except:
            i_line, has_pos = -1, False
        
        # sec: 対応するpyコード
        
        codes_py = []
        if has_pos and i_line > self.i_E_curr: # if: 未書出し行有り
            
            if i_from is None:
                i_B = self.i_E_curr + 1
            else:
                i_B = i_from
            if i_to is None:
                i_E = i_line
            else:
                i_E = i_to
            
            codes_py = self.codes[i_B:i_E + 1] # 未書出し行の部分を切り出し
            
            self.i_E_curr = i_E
            
        return codes_py
    
# ASTコード解析結果を分かり易くまとめてテキスト形式で出力、Pythonの元コードと合わせて併記
def print_ast(
    path_in = None, # pyソースコードのパス ※下記node&code or path_inの一方を指定
    node = None, code = None, # AST解析結果のツリーオブジェクト、pyソースコードのテキスト
    path_out = None): # 出力ファイルへのパス
    
    # sec: 引数チェック
    
    if pathlib.Path(str(node)).exists(): # if: 第1引数が有効なパス
        path_in = str(node)
        node = None # nodeは無効に
    
    if path_out is None: # if: 出力パスの指定なし
        if path_in is None:
            path_out = "print_ast.py"
        else:
            path_out = pathlib.Path(path_in).stem + ".print_ast.py" # 自動で命名
    
    # sec: main
    
    if node is not None:

        # sec: AST可視化
            
        AstResultPrinter.print_ast(node, code, path_out)
    
    elif path_in is not None:
        
        # sec: AST解析
        
        with open(path_in) as file:
            code = file.read()
        
        node = ast.parse(code)
        
        # sec: AST可視化
            
        AstResultPrinter.print_ast(node, code, path_out)


# sec: entry

if __name__ == "__main__": main()

出力結果例

前述の試作したコードを実行して得られる出力結果(Pythonの元コードと併記して構造を可視化し、分かり易くまとめてテキスト形式で出力したもの)は、例えば、

出力結果
>============================================================:py
   1|py: # -*- coding: utf-8 -*-
   2|py: 
   3|py: import numpy
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   3: 0|    Import {names: [alias]}
       |        alias {name: 'numpy', asname: None}
>============================================================:py
   4|py: import numpy as np
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   4: 0|    Import {names: [alias]}
       |        alias {name: 'numpy', asname: 'np'}
>============================================================:py
   5|py: from numpy import random, a, b, c
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   5: 0|    ImportFrom {module: 'numpy', names: [alias, alias, alias, alias], level: 0}
       |        alias {name: 'random', asname: None}
       |        alias {name: 'a', asname: None}
       |        alias {name: 'b', asname: None}
       |        alias {name: 'c', asname: None}
>============================================================:py
   6|py: from numpy import *
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   6: 0|    ImportFrom {module: 'numpy', names: [alias], level: 0}
       |        alias {name: '*', asname: None}
>============================================================:py
   7|py: import scipy
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   7: 0|    Import {names: [alias]}
       |        alias {name: 'scipy', asname: None}
>============================================================:py
   8|py: import matplotlib.pyplot as plt
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
   8: 0|    Import {names: [alias]}
       |        alias {name: 'matplotlib.pyplot', asname: 'plt'}
>============================================================:py
   9|py: 
  10|py: # sec: main
  11|py: 
  12|py: def main():
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  12: 0|    FunctionDef {name: 'main', args: arguments, body: [Assign, Assign, Assign, Assign, Expr, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, Assign, AugAssign, AugAssign, Assign, AugAssign, If, Assign, Assign, For, For, For, While, Return, FunctionDef, Expr, ClassDef, Assign], decorator_list: [], returns: None}
       |        arguments {args: [], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
>============================================================:py
  13|py: 
  14|py:     # ●式
  15|py:     
  16|py:     d = Data() # データ格納オブジェクト
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  16: 4|        Assign {targets: [Name], value: Call}
  16: 4|W           Name {id: 'd'}
  16: 8|            Call {func: Name, args: [], keywords: []}
  16: 8|R               Name {id: 'Data'}
>============================================================:py
  17|py:     d.x = Data(0xABC)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  17: 4|        Assign {targets: [Attribute], value: Call}
  17: 4|W           Attribute {value: Name, attr: 'x'}
  17: 4|R               Name {id: 'd'}
  17:10|            Call {func: Name, args: [Constant], keywords: []}
  17:10|R               Name {id: 'Data'}
  17:15|                Constant {value: 2748}
>============================================================:py
  18|py:     d.x.y = Data(0b1010_1111, numpy.a)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  18: 4|        Assign {targets: [Attribute], value: Call}
  18: 4|W           Attribute {value: Attribute, attr: 'y'}
  18: 4|R               Attribute {value: Name, attr: 'x'}
  18: 4|R                   Name {id: 'd'}
  18:12|            Call {func: Name, args: [Constant, Attribute], keywords: []}
  18:12|R               Name {id: 'Data'}
  18:17|                Constant {value: 175}
  18:30|R               Attribute {value: Name, attr: 'a'}
  18:30|R                   Name {id: 'numpy'}
>============================================================:py
  19|py:     d.x.y.z = 0
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  19: 4|        Assign {targets: [Attribute], value: Constant}
  19: 4|W           Attribute {value: Attribute, attr: 'z'}
  19: 4|R               Attribute {value: Attribute, attr: 'y'}
  19: 4|R                   Attribute {value: Name, attr: 'x'}
  19: 4|R                       Name {id: 'd'}
  19:14|            Constant {value: 0}
>============================================================:py
  20|py:     
  21|py:     func_A(d, 0)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  21: 4|        Expr {value: Call}
  21: 4|            Call {func: Name, args: [Name, Constant], keywords: []}
  21: 4|R               Name {id: 'func_A'}
  21:11|R               Name {id: 'd'}
  21:14|                Constant {value: 0}
>============================================================:py
  22|py:     y = func_A(d, 0)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  22: 4|        Assign {targets: [Name], value: Call}
  22: 4|W           Name {id: 'y'}
  22: 8|            Call {func: Name, args: [Name, Constant], keywords: []}
  22: 8|R               Name {id: 'func_A'}
  22:15|R               Name {id: 'd'}
  22:18|                Constant {value: 0}
>============================================================:py
  23|py:     f = lambda x: x**2
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  23: 4|        Assign {targets: [Name], value: Lambda}
  23: 4|W           Name {id: 'f'}
  23: 8|            Lambda {args: arguments, body: BinOp}
       |                arguments {args: [arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
  23:15|                    arg {arg: 'x', annotation: None}
  23:18|                BinOp {left: Name, op: Pow, right: Constant}
  23:18|R                   Name {id: 'x'}
       |                    Pow {}
  23:21|                    Constant {value: 2}
>============================================================:py
  24|py: 
  25|py:     a = numpy.a.b.c.arange(0, 1, 0.1, dtype=numpy.float) # 名前空間参照
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  25: 4|        Assign {targets: [Name], value: Call}
  25: 4|W           Name {id: 'a'}
  25: 8|            Call {func: Attribute, args: [Constant, Constant, Constant], keywords: [keyword]}
  25: 8|R               Attribute {value: Attribute, attr: 'arange'}
  25: 8|R                   Attribute {value: Attribute, attr: 'c'}
  25: 8|R                       Attribute {value: Attribute, attr: 'b'}
  25: 8|R                           Attribute {value: Name, attr: 'a'}
  25: 8|R                               Name {id: 'numpy'}
  25:27|                Constant {value: 0}
  25:30|                Constant {value: 1}
  25:33|                Constant {value: 0.1}
  25:38|                keyword {arg: 'dtype', value: Attribute}
  25:44|R                   Attribute {value: Name, attr: 'float'}
  25:44|R                       Name {id: 'numpy'}
>============================================================:py
  26|py:     a[0], a[1+2*3**4] = 10, 11
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  26: 4|        Assign {targets: [Tuple], value: Tuple}
  26: 4|W           Tuple {elts: [Subscript, Subscript]}
  26: 4|W               Subscript {value: Name, slice: Constant}
  26: 4|R                   Name {id: 'a'}
  26: 6|                    Constant {value: 0}
  26:10|W               Subscript {value: Name, slice: BinOp}
  26:10|R                   Name {id: 'a'}
  26:12|                    BinOp {left: Constant, op: Add, right: BinOp}
  26:12|                        Constant {value: 1}
       |                        Add {}
  26:14|                        BinOp {left: Constant, op: Mult, right: BinOp}
  26:14|                            Constant {value: 2}
       |                            Mult {}
  26:16|                            BinOp {left: Constant, op: Pow, right: Constant}
  26:16|                                Constant {value: 3}
       |                                Pow {}
  26:19|                                Constant {value: 4}
  26:24|R           Tuple {elts: [Constant, Constant]}
  26:24|                Constant {value: 10}
  26:28|                Constant {value: 11}
>============================================================:py
  27|py:     
  28|py:     i = 0
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  28: 4|        Assign {targets: [Name], value: Constant}
  28: 4|W           Name {id: 'i'}
  28: 8|            Constant {value: 0}
>============================================================:py
  29|py:     d.a = zeros((2, 3))
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  29: 4|        Assign {targets: [Attribute], value: Call}
  29: 4|W           Attribute {value: Name, attr: 'a'}
  29: 4|R               Name {id: 'd'}
  29:10|            Call {func: Name, args: [Tuple], keywords: []}
  29:10|R               Name {id: 'zeros'}
  29:16|R               Tuple {elts: [Constant, Constant]}
  29:17|                    Constant {value: 2}
  29:20|                    Constant {value: 3}
>============================================================:py
  30|py:     d.a[i + 1][2] = 11.3
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  30: 4|        Assign {targets: [Subscript], value: Constant}
  30: 4|W           Subscript {value: Subscript, slice: Constant}
  30: 4|R               Subscript {value: Attribute, slice: BinOp}
  30: 4|R                   Attribute {value: Name, attr: 'a'}
  30: 4|R                       Name {id: 'd'}
  30: 8|                    BinOp {left: Name, op: Add, right: Constant}
  30: 8|R                       Name {id: 'i'}
       |                        Add {}
  30:12|                        Constant {value: 1}
  30:15|                Constant {value: 2}
  30:20|            Constant {value: 11.3}
>============================================================:py
  31|py:     d.a[1, d.x.y.z] = d.a[d.x.y.z + i]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  31: 4|        Assign {targets: [Subscript], value: Subscript}
  31: 4|W           Subscript {value: Attribute, slice: Tuple}
  31: 4|R               Attribute {value: Name, attr: 'a'}
  31: 4|R                   Name {id: 'd'}
  31: 8|R               Tuple {elts: [Constant, Attribute]}
  31: 8|                    Constant {value: 1}
  31:11|R                   Attribute {value: Attribute, attr: 'z'}
  31:11|R                       Attribute {value: Attribute, attr: 'y'}
  31:11|R                           Attribute {value: Name, attr: 'x'}
  31:11|R                               Name {id: 'd'}
  31:22|R           Subscript {value: Attribute, slice: BinOp}
  31:22|R               Attribute {value: Name, attr: 'a'}
  31:22|R                   Name {id: 'd'}
  31:26|                BinOp {left: Attribute, op: Add, right: Name}
  31:26|R                   Attribute {value: Attribute, attr: 'z'}
  31:26|R                       Attribute {value: Attribute, attr: 'y'}
  31:26|R                           Attribute {value: Name, attr: 'x'}
  31:26|R                               Name {id: 'd'}
       |                    Add {}
  31:36|R                   Name {id: 'i'}
>============================================================:py
  32|py:     
  33|py:     a, b, c = 1, 2, 3
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  33: 4|        Assign {targets: [Tuple], value: Tuple}
  33: 4|W           Tuple {elts: [Name, Name, Name]}
  33: 4|W               Name {id: 'a'}
  33: 7|W               Name {id: 'b'}
  33:10|W               Name {id: 'c'}
  33:14|R           Tuple {elts: [Constant, Constant, Constant]}
  33:14|                Constant {value: 1}
  33:17|                Constant {value: 2}
  33:20|                Constant {value: 3}
>============================================================:py
  34|py:     y1, y2, y3 = func_A(d, 0)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  34: 4|        Assign {targets: [Tuple], value: Call}
  34: 4|W           Tuple {elts: [Name, Name, Name]}
  34: 4|W               Name {id: 'y1'}
  34: 8|W               Name {id: 'y2'}
  34:12|W               Name {id: 'y3'}
  34:17|            Call {func: Name, args: [Name, Constant], keywords: []}
  34:17|R               Name {id: 'func_A'}
  34:24|R               Name {id: 'd'}
  34:27|                Constant {value: 0}
>============================================================:py
  35|py:     
  36|py:     a = [1, 2, 3]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  36: 4|        Assign {targets: [Name], value: List}
  36: 4|W           Name {id: 'a'}
  36: 8|R           List {elts: [Constant, Constant, Constant]}
  36: 9|                Constant {value: 1}
  36:12|                Constant {value: 2}
  36:15|                Constant {value: 3}
>============================================================:py
  37|py:     a = [i + 1 for i in range(10)]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  37: 4|        Assign {targets: [Name], value: ListComp}
  37: 4|W           Name {id: 'a'}
  37: 8|            ListComp {elt: BinOp, generators: [comprehension]}
  37: 9|                BinOp {left: Name, op: Add, right: Constant}
  37: 9|R                   Name {id: 'i'}
       |                    Add {}
  37:13|                    Constant {value: 1}
       |                comprehension {target: Name, iter: Call, ifs: [], is_async: 0}
  37:19|W                   Name {id: 'i'}
  37:24|                    Call {func: Name, args: [Constant], keywords: []}
  37:24|R                       Name {id: 'range'}
  37:30|                        Constant {value: 10}
>============================================================:py
  38|py:     a = [i + 1 for i in range(10) if i > 5]
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  38: 4|        Assign {targets: [Name], value: ListComp}
  38: 4|W           Name {id: 'a'}
  38: 8|            ListComp {elt: BinOp, generators: [comprehension]}
  38: 9|                BinOp {left: Name, op: Add, right: Constant}
  38: 9|R                   Name {id: 'i'}
       |                    Add {}
  38:13|                    Constant {value: 1}
       |                comprehension {target: Name, iter: Call, ifs: [Compare], is_async: 0}
  38:19|W                   Name {id: 'i'}
  38:24|                    Call {func: Name, args: [Constant], keywords: []}
  38:24|R                       Name {id: 'range'}
  38:30|                        Constant {value: 10}
  38:37|                    Compare {left: Name, ops: [Gt], comparators: [Constant]}
  38:37|R                       Name {id: 'i'}
       |                        Gt {}
  38:41|                        Constant {value: 5}
>============================================================:py
  39|py:     a = {"a": 1, "b": a}
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  39: 4|        Assign {targets: [Name], value: Dict}
  39: 4|W           Name {id: 'a'}
  39: 8|            Dict {keys: [Constant, Constant], values: [Constant, Name]}
  39: 9|                Constant {value: 'a'}
  39:17|                Constant {value: 'b'}
  39:14|                Constant {value: 1}
  39:22|R               Name {id: 'a'}
>============================================================:py
  40|py:     
  41|py:     # ●行列
  42|py:     
  43|py:     d.a[0, :] = 1
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  43: 4|        Assign {targets: [Subscript], value: Constant}
  43: 4|W           Subscript {value: Attribute, slice: Tuple}
  43: 4|R               Attribute {value: Name, attr: 'a'}
  43: 4|R                   Name {id: 'd'}
  43: 8|R               Tuple {elts: [Constant, Slice]}
  43: 8|                    Constant {value: 0}
  43:11|                    Slice {lower: None, upper: None, step: None}
  43:16|            Constant {value: 1}
>============================================================:py
  44|py:     d.a[:, 1] += 13.4
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  44: 4|        AugAssign {target: Subscript, op: Add, value: Constant}
  44: 4|W           Subscript {value: Attribute, slice: Tuple}
  44: 4|R               Attribute {value: Name, attr: 'a'}
  44: 4|R                   Name {id: 'd'}
  44: 8|R               Tuple {elts: [Slice, Constant]}
  44: 8|                    Slice {lower: None, upper: None, step: None}
  44:11|                    Constant {value: 1}
       |            Add {}
  44:17|            Constant {value: 13.4}
>============================================================:py
  45|py:     d.a[1, 1:3] *= 14.4
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  45: 4|        AugAssign {target: Subscript, op: Mult, value: Constant}
  45: 4|W           Subscript {value: Attribute, slice: Tuple}
  45: 4|R               Attribute {value: Name, attr: 'a'}
  45: 4|R                   Name {id: 'd'}
  45: 8|R               Tuple {elts: [Constant, Slice]}
  45: 8|                    Constant {value: 1}
  45:11|                    Slice {lower: Constant, upper: Constant, step: None}
  45:11|                        Constant {value: 1}
  45:13|                        Constant {value: 3}
       |            Mult {}
  45:19|            Constant {value: 14.4}
>============================================================:py
  46|py:     d.b = d.a @ d.a.T
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  46: 4|        Assign {targets: [Attribute], value: BinOp}
  46: 4|W           Attribute {value: Name, attr: 'b'}
  46: 4|R               Name {id: 'd'}
  46:10|            BinOp {left: Attribute, op: MatMult, right: Attribute}
  46:10|R               Attribute {value: Name, attr: 'a'}
  46:10|R                   Name {id: 'd'}
       |                MatMult {}
  46:16|R               Attribute {value: Attribute, attr: 'T'}
  46:16|R                   Attribute {value: Name, attr: 'a'}
  46:16|R                       Name {id: 'd'}
>============================================================:py
  47|py:     d.b @= d.a
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  47: 4|        AugAssign {target: Attribute, op: MatMult, value: Attribute}
  47: 4|W           Attribute {value: Name, attr: 'b'}
  47: 4|R               Name {id: 'd'}
       |            MatMult {}
  47:11|R           Attribute {value: Name, attr: 'a'}
  47:11|R               Name {id: 'd'}
>============================================================:py
  48|py:     
  49|py:     # ●構文
  50|py:     
  51|py:     if d.x > 0:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  51: 4|        If {test: Compare, body: [Assign, Return], orelse: [If]}
  51: 7|            Compare {left: Attribute, ops: [Gt], comparators: [Constant]}
  51: 7|R               Attribute {value: Name, attr: 'x'}
  51: 7|R                   Name {id: 'd'}
       |                Gt {}
  51:13|                Constant {value: 0}
>============================================================:py
  52|py:         d.y = y
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  52: 8|            Assign {targets: [Attribute], value: Name}
  52: 8|W               Attribute {value: Name, attr: 'y'}
  52: 8|R                   Name {id: 'd'}
  52:14|R               Name {id: 'y'}
>============================================================:py
  53|py:         return y
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  53: 8|            Return {value: Name}
  53:15|R               Name {id: 'y'}
>============================================================:py
  54|py:     elif y < 0 and \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  54: 4|            If {test: BoolOp, body: [Return], orelse: [Pass]}
  54: 9|                BoolOp {op: Or, values: [BoolOp, UnaryOp]}
       |                    Or {}
  54: 9|                    BoolOp {op: And, values: [Compare, Compare]}
       |                        And {}
  54: 9|                        Compare {left: Name, ops: [Lt], comparators: [Constant]}
  54: 9|R                           Name {id: 'y'}
       |                            Lt {}
  54:13|                            Constant {value: 0}
>============================================================:py
  55|py:         y | x & a <= 0 or \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  55: 8|                        Compare {left: BinOp, ops: [LtE], comparators: [Constant]}
  55: 8|                            BinOp {left: Name, op: BitOr, right: BinOp}
  55: 8|R                               Name {id: 'y'}
       |                                BitOr {}
  55:12|                                BinOp {left: Name, op: BitAnd, right: Name}
  55:12|R                                   Name {id: 'x'}
       |                                    BitAnd {}
  55:16|R                                   Name {id: 'a'}
       |                            LtE {}
  55:21|                            Constant {value: 0}
>============================================================:py
  56|py:         not y << 1 == 0:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  56: 8|                    UnaryOp {op: Not, operand: Compare}
       |                        Not {}
  56:12|                        Compare {left: BinOp, ops: [Eq], comparators: [Constant]}
  56:12|                            BinOp {left: Name, op: LShift, right: Constant}
  56:12|R                               Name {id: 'y'}
       |                                LShift {}
  56:17|                                Constant {value: 1}
       |                            Eq {}
  56:22|                            Constant {value: 0}
>============================================================:py
  57|py:         return y
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  57: 8|                Return {value: Name}
  57:15|R                   Name {id: 'y'}
>============================================================:py
  58|py:     else:
  59|py:         pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  59: 8|                Pass {}
>============================================================:py
  60|py:     
  61|py:     b = \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  61: 4|        Assign {targets: [Name], value: BinOp}
  61: 4|W           Name {id: 'b'}
>============================================================:py
  62|py:         tanh(b**2) + \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  62: 8|            BinOp {left: Call, op: Add, right: Call}
  62: 8|                Call {func: Name, args: [BinOp], keywords: []}
  62: 8|R                   Name {id: 'tanh'}
  62:13|                    BinOp {left: Name, op: Pow, right: Constant}
  62:13|R                       Name {id: 'b'}
       |                        Pow {}
  62:16|                        Constant {value: 2}
       |                Add {}
>============================================================:py
  63|py:         tanh(b)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  63: 8|                Call {func: Name, args: [Name], keywords: []}
  63: 8|R                   Name {id: 'tanh'}
  63:13|R                   Name {id: 'b'}
>============================================================:py
  64|py:         
  65|py:     a_out = a.copy()
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  65: 4|        Assign {targets: [Name], value: Call}
  65: 4|W           Name {id: 'a_out'}
  65:12|            Call {func: Attribute, args: [], keywords: []}
  65:12|R               Attribute {value: Name, attr: 'copy'}
  65:12|R                   Name {id: 'a'}
>============================================================:py
  66|py:     for i_a in range(d.a[0], len(a) - 1, y):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  66: 4|        For {target: Name, iter: Call, body: [Assign, Break, Continue], orelse: []}
  66: 8|W           Name {id: 'i_a'}
  66:15|            Call {func: Name, args: [Subscript, BinOp, Name], keywords: []}
  66:15|R               Name {id: 'range'}
  66:21|R               Subscript {value: Attribute, slice: Constant}
  66:21|R                   Attribute {value: Name, attr: 'a'}
  66:21|R                       Name {id: 'd'}
  66:25|                    Constant {value: 0}
  66:29|                BinOp {left: Call, op: Sub, right: Constant}
  66:29|                    Call {func: Name, args: [Name], keywords: []}
  66:29|R                       Name {id: 'len'}
  66:33|R                       Name {id: 'a'}
       |                    Sub {}
  66:38|                    Constant {value: 1}
  66:41|R               Name {id: 'y'}
>============================================================:py
  67|py:         a_out[i_a] = \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  67: 8|            Assign {targets: [Subscript], value: BinOp}
  67: 8|W               Subscript {value: Name, slice: Name}
  67: 8|R                   Name {id: 'a_out'}
  67:14|R                   Name {id: 'i_a'}
>============================================================:py
  68|py:             tanh(a[i_a]**2) + \
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  68:12|                BinOp {left: Call, op: Add, right: Call}
  68:12|                    Call {func: Name, args: [BinOp], keywords: []}
  68:12|R                       Name {id: 'tanh'}
  68:17|                        BinOp {left: Subscript, op: Pow, right: Constant}
  68:17|R                           Subscript {value: Name, slice: Name}
  68:17|R                               Name {id: 'a'}
  68:19|R                               Name {id: 'i_a'}
       |                            Pow {}
  68:25|                            Constant {value: 2}
       |                    Add {}
>============================================================:py
  69|py:             tanh(a[i_a + 1])
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  69:12|                    Call {func: Name, args: [Subscript], keywords: []}
  69:12|R                       Name {id: 'tanh'}
  69:17|R                       Subscript {value: Name, slice: BinOp}
  69:17|R                           Name {id: 'a'}
  69:19|                            BinOp {left: Name, op: Add, right: Constant}
  69:19|R                               Name {id: 'i_a'}
       |                                Add {}
  69:25|                                Constant {value: 1}
>============================================================:py
  70|py:         break
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  70: 8|            Break {}
>============================================================:py
  71|py:         continue
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  71: 8|            Continue {}
>============================================================:py
  72|py: 
  73|py:     for i_a, a in enumerate(range(10)):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  73: 4|        For {target: Tuple, iter: Call, body: [Expr], orelse: [Expr]}
  73: 8|W           Tuple {elts: [Name, Name]}
  73: 8|W               Name {id: 'i_a'}
  73:13|W               Name {id: 'a'}
  73:18|            Call {func: Name, args: [Call], keywords: []}
  73:18|R               Name {id: 'enumerate'}
  73:28|                Call {func: Name, args: [Constant], keywords: []}
  73:28|R                   Name {id: 'range'}
  73:34|                    Constant {value: 10}
>============================================================:py
  74|py:         func_A(a)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  74: 8|            Expr {value: Call}
  74: 8|                Call {func: Name, args: [Name], keywords: []}
  74: 8|R                   Name {id: 'func_A'}
  74:15|R                   Name {id: 'a'}
>============================================================:py
  75|py:     else:
  76|py:         func_A(a)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  76: 8|            Expr {value: Call}
  76: 8|                Call {func: Name, args: [Name], keywords: []}
  76: 8|R                   Name {id: 'func_A'}
  76:15|R                   Name {id: 'a'}
>============================================================:py
  77|py: 
  78|py:     for i_a, (a, b) in enumerate(zip(range(10), range(5))):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  78: 4|        For {target: Tuple, iter: Call, body: [Pass], orelse: []}
  78: 8|W           Tuple {elts: [Name, Tuple]}
  78: 8|W               Name {id: 'i_a'}
  78:13|W               Tuple {elts: [Name, Name]}
  78:14|W                   Name {id: 'a'}
  78:17|W                   Name {id: 'b'}
  78:23|            Call {func: Name, args: [Call], keywords: []}
  78:23|R               Name {id: 'enumerate'}
  78:33|                Call {func: Name, args: [Call, Call], keywords: []}
  78:33|R                   Name {id: 'zip'}
  78:37|                    Call {func: Name, args: [Constant], keywords: []}
  78:37|R                       Name {id: 'range'}
  78:43|                        Constant {value: 10}
  78:48|                    Call {func: Name, args: [Constant], keywords: []}
  78:48|R                       Name {id: 'range'}
  78:54|                        Constant {value: 5}
>============================================================:py
  79|py:         pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  79: 8|            Pass {}
>============================================================:py
  80|py:     
  81|py:     while y > 0:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  81: 4|        While {test: Compare, body: [Break, Continue], orelse: []}
  81:10|            Compare {left: Name, ops: [Gt], comparators: [Constant]}
  81:10|R               Name {id: 'y'}
       |                Gt {}
  81:14|                Constant {value: 0}
>============================================================:py
  82|py:         break
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  82: 8|            Break {}
>============================================================:py
  83|py:         continue
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  83: 8|            Continue {}
>============================================================:py
  84|py:     
  85|py:     return a
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  85: 4|        Return {value: Name}
  85:11|R           Name {id: 'a'}
>============================================================:py
  86|py:     
  87|py:     # ●内包
  88|py:     
  89|py:     def func_A(a):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  89: 4|        FunctionDef {name: 'func_A', args: arguments, body: [Return], decorator_list: [], returns: None}
       |            arguments {args: [arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
  89:15|                arg {arg: 'a', annotation: None}
>============================================================:py
  90|py:         return a
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  90: 8|            Return {value: Name}
  90:15|R               Name {id: 'a'}
>============================================================:py
  91|py:     func_A(a)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  91: 4|        Expr {value: Call}
  91: 4|            Call {func: Name, args: [Name], keywords: []}
  91: 4|R               Name {id: 'func_A'}
  91:11|R               Name {id: 'a'}
>============================================================:py
  92|py:     
  93|py:     class Data11: pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  93: 4|        ClassDef {name: 'Data11', bases: [], keywords: [], body: [Pass], decorator_list: []}
  93:18|            Pass {}
>============================================================:py
  94|py:     a = Data11()
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  94: 4|        Assign {targets: [Name], value: Call}
  94: 4|W           Name {id: 'a'}
  94: 8|            Call {func: Name, args: [], keywords: []}
  94: 8|R               Name {id: 'Data11'}
>============================================================:py
  95|py: 
  96|py: # ●関数
  97|py: 
  98|py: def func_A(
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  98: 0|    FunctionDef {name: 'func_A', args: arguments, body: [Return], decorator_list: [], returns: None}
       |        arguments {args: [arg, arg, arg, arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: [Constant, Constant, Constant]}
>============================================================:py
  99|py:     d, 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
  99: 4|            arg {arg: 'd', annotation: None}
>============================================================:py
 100|py:     x = 0,
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 100: 4|            arg {arg: 'x', annotation: None}
>============================================================:py
 101|py:     x2 = 0,
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 101: 4|            arg {arg: 'x2', annotation: None}
>============================================================:py
 102|py:     x3 = 0):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 102: 4|            arg {arg: 'x3', annotation: None}
 100: 8|            Constant {value: 0}
 101: 9|            Constant {value: 0}
 102: 9|            Constant {value: 0}
>============================================================:py
 103|py:     
 104|py:     return 2 * x + d.x, x**2, x**3
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 104: 4|        Return {value: Tuple}
 104:11|R           Tuple {elts: [BinOp, BinOp, BinOp]}
 104:11|                BinOp {left: BinOp, op: Add, right: Attribute}
 104:11|                    BinOp {left: Constant, op: Mult, right: Name}
 104:11|                        Constant {value: 2}
       |                        Mult {}
 104:15|R                       Name {id: 'x'}
       |                    Add {}
 104:19|R                   Attribute {value: Name, attr: 'x'}
 104:19|R                       Name {id: 'd'}
 104:24|                BinOp {left: Name, op: Pow, right: Constant}
 104:24|R                   Name {id: 'x'}
       |                    Pow {}
 104:27|                    Constant {value: 2}
 104:30|                BinOp {left: Name, op: Pow, right: Constant}
 104:30|R                   Name {id: 'x'}
       |                    Pow {}
 104:33|                    Constant {value: 3}
>============================================================:py
 105|py: 
 106|py: class Data1: pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 106: 0|    ClassDef {name: 'Data1', bases: [], keywords: [], body: [Pass], decorator_list: []}
 106:13|        Pass {}
>============================================================:py
 107|py: class Data2: pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 107: 0|    ClassDef {name: 'Data2', bases: [], keywords: [], body: [Pass], decorator_list: []}
 107:13|        Pass {}
>============================================================:py
 108|py: class Data3: pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 108: 0|    ClassDef {name: 'Data3', bases: [], keywords: [], body: [Pass], decorator_list: []}
 108:13|        Pass {}
>============================================================:py
 109|py: 
 110|py: # ●クラス
 111|py: 
 112|py: class Data(
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 112: 0|    ClassDef {name: 'Data', bases: [Name, Name, Name], keywords: [], body: [Assign, FunctionDef, FunctionDef, FunctionDef], decorator_list: []}
>============================================================:py
 113|py:     Data1, 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 113: 4|R       Name {id: 'Data1'}
>============================================================:py
 114|py:     Data2, 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 114: 4|R       Name {id: 'Data2'}
>============================================================:py
 115|py:     Data3):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 115: 4|R       Name {id: 'Data3'}
>============================================================:py
 116|py:     
 117|py:     # sec: 初期化
 118|py:     
 119|py:     gb_a = 1
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 119: 4|        Assign {targets: [Name], value: Constant}
 119: 4|W           Name {id: 'gb_a'}
 119:11|            Constant {value: 1}
>============================================================:py
 120|py:     
 121|py:     def __init__(self):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 121: 4|        FunctionDef {name: '__init__', args: arguments, body: [Assign, Assign], decorator_list: [], returns: None}
       |            arguments {args: [arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
 121:17|                arg {arg: 'self', annotation: None}
>============================================================:py
 122|py:         self.a = 12.34
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 122: 8|            Assign {targets: [Attribute], value: Constant}
 122: 8|W               Attribute {value: Name, attr: 'a'}
 122: 8|R                   Name {id: 'self'}
 122:17|                Constant {value: 12.34}
>============================================================:py
 123|py:         self.b = self.a**2
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 123: 8|            Assign {targets: [Attribute], value: BinOp}
 123: 8|W               Attribute {value: Name, attr: 'b'}
 123: 8|R                   Name {id: 'self'}
 123:17|                BinOp {left: Attribute, op: Pow, right: Constant}
 123:17|R                   Attribute {value: Name, attr: 'a'}
 123:17|R                       Name {id: 'self'}
       |                    Pow {}
 123:25|                    Constant {value: 2}
>============================================================:py
 124|py:     
 125|py:     # sec: 機能群
 126|py:     
 127|py:     def func_A(self):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 127: 4|        FunctionDef {name: 'func_A', args: arguments, body: [Return], decorator_list: [], returns: None}
       |            arguments {args: [arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
 127:15|                arg {arg: 'self', annotation: None}
>============================================================:py
 128|py:         return self.a + self.gb_a
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 128: 8|            Return {value: BinOp}
 128:15|                BinOp {left: Attribute, op: Add, right: Attribute}
 128:15|R                   Attribute {value: Name, attr: 'a'}
 128:15|R                       Name {id: 'self'}
       |                    Add {}
 128:24|R                   Attribute {value: Name, attr: 'gb_a'}
 128:24|R                       Name {id: 'self'}
>============================================================:py
 129|py:             
 130|py:     def func_B(self, x, y):
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 130: 4|        FunctionDef {name: 'func_B', args: arguments, body: [ClassDef, Return], decorator_list: [], returns: None}
       |            arguments {args: [arg, arg, arg], vararg: None, kwonlyargs: [], kw_defaults: [], kwarg: None, defaults: []}
 130:15|                arg {arg: 'self', annotation: None}
 130:21|                arg {arg: 'x', annotation: None}
 130:24|                arg {arg: 'y', annotation: None}
>============================================================:py
 131|py:         class Data11: pass
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 131: 8|            ClassDef {name: 'Data11', bases: [], keywords: [], body: [Pass], decorator_list: []}
 131:22|                Pass {}
>============================================================:py
 132|py:         return self.a * self.b + x / y + x // y + x % y
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 132: 8|            Return {value: BinOp}
 132:15|                BinOp {left: BinOp, op: Add, right: BinOp}
 132:15|                    BinOp {left: BinOp, op: Add, right: BinOp}
 132:15|                        BinOp {left: BinOp, op: Add, right: BinOp}
 132:15|                            BinOp {left: Attribute, op: Mult, right: Attribute}
 132:15|R                               Attribute {value: Name, attr: 'a'}
 132:15|R                                   Name {id: 'self'}
       |                                Mult {}
 132:24|R                               Attribute {value: Name, attr: 'b'}
 132:24|R                                   Name {id: 'self'}
       |                            Add {}
 132:33|                            BinOp {left: Name, op: Div, right: Name}
 132:33|R                               Name {id: 'x'}
       |                                Div {}
 132:37|R                               Name {id: 'y'}
       |                        Add {}
 132:41|                        BinOp {left: Name, op: FloorDiv, right: Name}
 132:41|R                           Name {id: 'x'}
       |                            FloorDiv {}
 132:46|R                           Name {id: 'y'}
       |                    Add {}
 132:50|                    BinOp {left: Name, op: Mod, right: Name}
 132:50|R                       Name {id: 'x'}
       |                        Mod {}
 132:54|R                       Name {id: 'y'}
>============================================================:py
 133|py: 
 134|py: # sec: entry
 135|py: 
 136|py: if __name__ == "__main__":
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 136: 0|    If {test: Compare, body: [Expr], orelse: []}
 136: 3|        Compare {left: Name, ops: [Eq], comparators: [Constant]}
 136: 3|R           Name {id: '__name__'}
       |            Eq {}
 136:15|            Constant {value: '__main__'}
>============================================================:py
 137|py:     main()
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :ast
 137: 4|        Expr {value: Call}
 137: 4|            Call {func: Name, args: [], keywords: []}
 137: 4|R               Name {id: 'main'}

この時、サンプルとして使用したPythonの元コードは、(特に意味のない適当なコード)

サンプル用のPythonの元コード
# -*- coding: utf-8 -*-

import numpy
import numpy as np
from numpy import random, a, b, c
from numpy import *
import scipy
import matplotlib.pyplot as plt

# sec: main

def main():

    # ●式
    
    d = Data() # データ格納オブジェクト
    d.x = Data(0xABC)
    d.x.y = Data(0b1010_1111, numpy.a)
    d.x.y.z = 0
    
    func_A(d, 0)
    y = func_A(d, 0)
    f = lambda x: x**2

    a = numpy.a.b.c.arange(0, 1, 0.1, dtype=numpy.float) # 名前空間参照
    a[0], a[1+2*3**4] = 10, 11
    
    i = 0
    d.a = zeros((2, 3))
    d.a[i + 1][2] = 11.3
    d.a[1, d.x.y.z] = d.a[d.x.y.z + i]
    
    a, b, c = 1, 2, 3
    y1, y2, y3 = func_A(d, 0)
    
    a = [1, 2, 3]
    a = [i + 1 for i in range(10)]
    a = [i + 1 for i in range(10) if i > 5]
    a = {"a": 1, "b": a}
    
    # ●行列
    
    d.a[0, :] = 1
    d.a[:, 1] += 13.4
    d.a[1, 1:3] *= 14.4
    d.b = d.a @ d.a.T
    d.b @= d.a
    
    # ●構文
    
    if d.x > 0:
        d.y = y
        return y
    elif y < 0 and \
        y | x & a <= 0 or \
        not y << 1 == 0:
        return y
    else:
        pass
    
    b = \
        tanh(b**2) + \
        tanh(b)
        
    a_out = a.copy()
    for i_a in range(d.a[0], len(a) - 1, y):
        a_out[i_a] = \
            tanh(a[i_a]**2) + \
            tanh(a[i_a + 1])
        break
        continue

    for i_a, a in enumerate(range(10)):
        func_A(a)
    else:
        func_A(a)

    for i_a, (a, b) in enumerate(zip(range(10), range(5))):
        pass
    
    while y > 0:
        break
        continue
    
    return a
    
    # ●内包
    
    def func_A(a):
        return a
    func_A(a)
    
    class Data11: pass
    a = Data11()

# ●関数

def func_A(
    d, 
    x = 0,
    x2 = 0,
    x3 = 0):
    
    return 2 * x + d.x, x**2, x**3

class Data1: pass
class Data2: pass
class Data3: pass

# ●クラス

class Data(
    Data1, 
    Data2, 
    Data3):
    
    # sec: 初期化
    
    gb_a = 1
    
    def __init__(self):
        self.a = 12.34
        self.b = self.a**2
    
    # sec: 機能群
    
    def func_A(self):
        return self.a + self.gb_a
            
    def func_B(self, x, y):
        class Data11: pass
        return self.a * self.b + x / y + x // y + x % y

# sec: entry

if __name__ == "__main__":
    main()

環境

Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021) [MSC v.1928 64 bit (AMD64)] on Win 10

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?