symtable --- コンパイラーの記号表へのアクセス¶
ソースコード: Lib/symtable.py
記号表は、バイトコードを生成する直前にコンパイラーが AST から生成します。
コード内のすべての識別子のスコープを決める役割を担います。
symtable はこれらの記号表を調べるためのインターフェースを提供します。
記号表の生成¶
- symtable.symtable(code, filename, compile_type, *, module=None)¶
Python ソース code のトップレベルの
SymbolTableを返します。 filename はコードを含むファイルの名前です。 compile_type はcompile()の mode 引数と同様です。 省略可能な module 引数はモジュール名を指定します。 構文警告をモジュール名によって曖昧さなく フィルター するために必要です。Added in version 3.15: module 引数が追加されました。
記号表の検査¶
- class symtable.SymbolTableType¶
SymbolTableオブジェクトの種類を示す列挙型です。- MODULE = "module"¶
モジュールの記号表に使われます。
- FUNCTION = "function"¶
関数の記号表に使われます。
- CLASS = "class"¶
クラスの記号表に使われます。
次のメンバーは、アノテーションスコープ の種類を表します。
- ANNOTATION = "annotation"¶
Used for annotations if
from __future__ import annotationsis active.
- TYPE_VARIABLE = "type variable"¶
型変数、つまり TypeVar、TypeVarTuple、ParamSpec のいずれかのオブジェクト 1 つについて、その上限境界、制約タプル、デフォルト値の記号表に使われます (後ろの 2 つは上限境界や制約タプルをサポートしません)。
Added in version 3.13.
- class symtable.SymbolTable¶
ブロックに対する名前空間の記号表。コンストラクタはパブリックではありません。
- get_type()¶
記号表の種類を返します。 戻り値は
SymbolTableType列挙型のメンバーです。バージョン 3.12 で変更: 戻り値として
'annotation'、'TypeVar bound'、'type alias'、'type parameter'が追加されました。バージョン 3.13 で変更: 戻り値が
SymbolTableType列挙型のメンバーになりました。返される文字列の具体的な値は将来変わる可能性があるため、文字列を直接書くのではなく
SymbolTableTypeのメンバーを使うことを推奨します。
- get_id()¶
記号表の識別子を返します。
- get_name()¶
記号表の名前を返します。 クラスの記号表ならクラス名、関数の記号表なら関数名、グローバルな記号表 (
get_type()が'module'を返すもの) なら'top'です。 ジェネリッククラス、関数、型エイリアスで使う型パラメータースコープの場合は、対応するクラス、関数、型エイリアスの名前です。 型エイリアススコープの場合は型エイリアスの名前です。TypeVarの上限境界スコープの場合は、そのTypeVarの名前です。
- get_lineno()¶
この記号表に対応するブロックの一行目の行番号を返します。
- is_optimized()¶
この記号表に含まれるローカル変数が最適化できるならば
Trueを返します。
- is_nested()¶
ブロックが入れ子のクラスまたは関数のとき
Trueを返します。
- has_children()¶
ブロックが入れ子の名前空間を含んでいるならば
Trueを返します。入れ子の名前空間はget_children()で得られます。
- get_identifiers()¶
記号表内の記号の名前を含むビューオブジェクトを返します。 ビューオブジェクトのドキュメント を参照してください。
- get_children()¶
入れ子になった記号表のリストを返します。
- class symtable.Function¶
関数またはメソッドの名前空間です。 このクラスは
SymbolTableを継承します。- get_parameters()¶
この関数の引数名からなるタプルを返します。
- get_locals()¶
この関数のローカル変数の名前からなるタプルを返します。
- get_globals()¶
この関数のグローバル変数の名前からなるタプルを返します。
- get_nonlocals()¶
この関数内で明示的に nonlocal と宣言された名前のタプルを返します。
- get_frees()¶
この関数内の 自由 (クロージャー) 変数 の名前のタプルを返します。
- class symtable.Class¶
クラスの名前空間です。 このクラスは
SymbolTableを継承します。- get_methods()¶
クラス内で宣言された、メソッドに相当する関数の名前のタプルを返します。
ここで「メソッド」とは、クラス本体で
defまたはasync defによって定義された すべての 関数を指します。より深いスコープ (内部クラスなど) で定義された関数は、
get_methods()の結果には含まれません。例えば:
>>> import symtable >>> st = symtable.symtable(''' ... def outer(): pass ... ... class A: ... def f(): ... def w(): pass ... ... def g(self): pass ... ... @classmethod ... async def h(cls): pass ... ... global outer ... def outer(self): pass ... ''', 'test', 'exec') >>> class_A = st.get_children()[2] >>> class_A.get_methods() ('f', 'g', 'h')
A().f()は実行時にTypeErrorを送出しますが、A.fはそれでもメソッドに相当する関数とみなされます。バージョン 3.14 で非推奨、バージョン 3.16 で削除予定.
- class symtable.Symbol¶
SymbolTableのエントリーでソースの識別子に対応するものです。コンストラクタはパブリックではありません。- get_name()¶
記号の名前を返します。
- is_referenced()¶
記号がそのブロックの中で使われていれば
Trueを返します。
- is_imported()¶
記号が import 文で作られたものならば
Trueを返します。
- is_parameter()¶
記号がパラメータならば
Trueを返します。
- is_type_parameter()¶
記号が型パラメーターであれば
Trueを返します。Added in version 3.14.
- is_global()¶
記号がグローバルならば
Trueを返します。
- is_nonlocal()¶
記号が非ローカルならば
Trueを返します。
- is_declared_global()¶
記号が global 文によってグローバルであると宣言されているなら
Trueを返します。
- is_local()¶
記号がそのブロックに対してローカルならば
Trueを返します。
- is_annotated()¶
記号が注釈付きならば
Trueを返します。Added in version 3.6.
- is_free()¶
記号がそのブロックの中で参照されていて、しかし代入は行われないならば
Trueを返します。
- is_cell()¶
入れ子のブロックで記号が参照され、代入はされていない場合に
Trueを返します。Added in version 3.15.
- is_free_class()¶
クラススコープの記号がメソッドから見て自由変数である場合、True を返します。
次に示す例について考えてみてください。:
def f(): x = 1 # 関数スコープ class C: x = 2 # クラススコープ def method(self): return x
この例では、クラススコープの記号
xはC.methodから見て自由変数とみなされます。 そのため、C.methodは実行時に 2 ではなく 1 を返せます。Added in version 3.14.
- is_assigned()¶
記号がそのブロックの中で代入されているならば
Trueを返します。
- is_comp_iter()¶
記号が内包表記の反復変数であれば
Trueを返します。Added in version 3.14.
- is_comp_cell()¶
記号がインライン化された内包表記のセルであれば
Trueを返します。Added in version 3.14.
- is_namespace()¶
名前の束縛が新たな名前空間を導入するならば
Trueを返します。名前が関数または class 文のターゲットとして使われるならば、真です。
例えば:
>>> table = symtable.symtable("def some_func(): pass", "string", "exec") >>> table.lookup("some_func").is_namespace() True
一つの名前が複数のオブジェクトに束縛されうることに注意しましょう。結果が
Trueであったとしても、その名前は他のオブジェクトにも束縛されるかもしれず、それがたとえば整数やリストであれば、そこでは新たな名前空間は導入されません。
- get_namespaces()¶
この名前に束縛された名前空間のリストを返します。
- get_namespace()¶
この名前に束縛された名前空間を返します。この名前に束縛された名前空間が複数あるか一つもないなら
ValueErrorが送出されます。
コマンドラインからの使用¶
Added in version 3.13.
symtable モジュールはコマンドラインからスクリプトとして実行できます。
python -m symtable [infile...]
指定した Python ソースファイルの記号表を生成し、標準出力に書き出します。 入力ファイルを指定しない場合は、標準入力から内容を読み込みます。