symtable — 訪問編譯器的符號表

原始碼: Lib/symtable.py


符號表由編譯器在生成位元組碼之前從 AST 生成。符號表負責計算程式碼中每個識別符號的作用域。symtable 提供了一個介面來檢查這些表。

生成符號表

symtable.symtable(code, filename, compile_type)

返回 Python 原始碼 code 的頂層 SymbolTablefilename 是包含程式碼的檔案的名稱。compile_type 類似於 compile()mode 引數。

檢查符號表

class symtable.SymbolTableType

一個列舉,指示 SymbolTable 物件的型別。

MODULE = "module"

用於模組的符號表。

FUNCTION = "function"

用於函式的符號表。

CLASS = "class"

用於類的符號表。

以下成員引用 註解作用域 的不同風格。

ANNOTATION = "annotation"

如果 from __future__ import annotations 處於活動狀態,則用於註解。

TYPE_ALIAS = "type alias"

用於 type 構造的符號表。

TYPE_PARAMETERS = "type parameters"

用於 泛型函式泛型類 的符號表。

TYPE_VARIABLE = "type variable"

用於形式意義上的單個型別變數(即 TypeVar、TypeVarTuple 或 ParamSpec 物件,後兩者不支援邊界或約束元組)的邊界、約束元組或預設值的符號表。

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

返回一個檢視物件,其中包含表中符號的名稱。請參閱檢視物件的文件

lookup(name)

在表中查詢 name 並返回 Symbol 例項。

get_symbols()

返回表中名稱的 Symbol 例項列表。

get_children()

返回巢狀符號表的列表。

class symtable.Function

函式或方法的名稱空間。此類繼承自 SymbolTable

get_parameters()

返回一個包含此函式引數名稱的元組。

get_locals()

返回一個包含此函式區域性變數名稱的元組。

get_globals()

返回一個包含此函式全域性變數名稱的元組。

get_nonlocals()

返回一個包含此函式中顯式宣告的非區域性變數名稱的元組。

get_frees()

返回一個包含此函式中自由(閉包)變數名稱的元組。

class symtable.Class

一個類的名稱空間。此類繼承自 SymbolTable

get_methods()

返回一個包含類中宣告的類似方法的函式名稱的元組。

此處,術語“方法”指代透過 defasync 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()[1]
>>> class_A.get_methods()
('f', 'g', 'h')

儘管 A().f() 在執行時會引發 TypeError,但 A.f 仍然被認為是類似方法的函式。

class symtable.Symbol

SymbolTable 中對應於原始碼中識別符號的條目。建構函式不是公開的。

get_name()

返回符號的名稱。

is_referenced()

如果符號在其塊中使用,則返回 True

is_imported()

如果符號是從匯入語句建立的,則返回 True

is_parameter()

如果符號是引數,則返回 True

is_global()

如果符號是全域性的,則返回 True

is_nonlocal()

如果符號是非區域性的,則返回 True

is_declared_global()

如果符號是透過 global 語句宣告為全域性的,則返回 True

is_local()

如果符號是其塊的本地符號,則返回 True

is_annotated()

如果符號被註釋,則返回 True

3.6 版本新增。

is_free()

如果符號在其塊中被引用,但未被賦值,則返回 True

is_assigned()

如果符號在其塊中被賦值,則返回 True

is_namespace()

如果名稱繫結引入新的名稱空間,則返回 True

如果名稱用作函式或類語句的目標,則此值將為 True。

例如

>>> table = symtable.symtable("def some_func(): pass", "string", "exec")
>>> table.lookup("some_func").is_namespace()
True

請注意,單個名稱可以繫結到多個物件。如果結果為 True,則該名稱也可能繫結到其他物件,例如 int 或 list,這些物件不會引入新的名稱空間。

get_namespaces()

返回繫結到此名稱的名稱空間列表。

get_namespace()

返回繫結到此名稱的名稱空間。 如果繫結到此名稱的名稱空間不止一個或沒有,則會引發 ValueError

命令列用法

3.13 版本中新增。

可以從命令列將 symtable 模組作為指令碼執行。

python -m symtable [infile...]

將為指定的 Python 原始檔生成符號表,並將其轉儲到標準輸出。 如果未指定輸入檔案,則從標準輸入讀取內容。