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 宣告的方法式函式的名稱。

在這裡,“方法”一詞指代透過 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()[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

在 3.14 版本加入。

is_global()

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

is_nonlocal()

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

is_declared_global()

如果符號用 global 語句宣告為全域性變數,則返回 True

is_local()

如果符號是其程式碼塊的區域性變數,則返回 True

is_annotated()

如果符號已被標註,則返回 True

在 3.6 版本加入。

is_free()

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

is_free_class()

如果類作用域符號從方法的角度來看是自由的,則返回 True

考慮以下示例

def f():
    x = 1  # function-scoped
    class C:
        x = 2  # class-scoped
        def method(self):
            return x

在此示例中,類作用域符號 xC.method 的角度來看被認為是自由的,從而允許後者在執行時返回 1 而不是 2

在 3.14 版本加入。

is_assigned()

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

is_comp_iter()

如果符號是推導式迭代變數,則返回 True

在 3.14 版本加入。

is_comp_cell()

如果符號是內聯推導式中的一個單元格,則返回 True

在 3.14 版本加入。

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 原始檔生成符號表並轉儲到標準輸出。如果未指定輸入檔案,則從標準輸入讀取內容。