symtable --- 存取編譯器的符號表

原始碼:Lib/symtable.py


符號表 (symbol table) 是在生成位元組碼 (bytecode) 之前由編譯器從 AST 生成的。符號表負責計算程式碼中每個識別器 (identifier) 的作用域。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"

用於泛型函式 (generic functions)泛型類別 (generic classes)的符號表。

TYPE_VARIABLE = "type variable"

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

在 3.13 版被加入.

class symtable.SymbolTable

一個區塊 (block) 的命名空間表 (namespace table) 。建構函式 (constructor) 並不公開。

get_type()

回傳符號表的類型。可能的值為 SymbolTableType 列舉的成員。

在 3.12 版的變更: 新增了 'annotation''TypeVar bound''type alias''type parameter' 作為可能的回傳值。

在 3.13 版的變更: 回傳值是 SymbolTableType 列舉的成員。

回傳字串的確切值在未來可能會發生變化,因此建議使用 SymbolTableType 成員而不是寫死 (hard-coded) 字串。

get_id()

回傳表的識別器。

get_name()

回傳表的名稱。如果表用於類別,則這是類別的名稱;如果表用於函式,則這是函式的名稱;如果表是全域的,則為 'top'get_type() 會回傳 'module')。對於型別參數作用域(用於泛型類別、函式和型別別名),它是底層類別、函式或型別別名的名稱。對於型別別名作用域,它是型別別名的名稱。對於 TypeVar 綁定作用域,它會是 TypeVar 的名稱。

get_lineno()

回傳此表所代表的區塊中第一行的編號。

is_optimized()

如果可以最佳化該表中的區域變數,則回傳 True

is_nested()

如果區塊是巢狀類別或函式,則回傳 True

has_children()

如果區塊內有巢狀命名空間,則回傳 True。這些可以透過 get_children() 獲得。

get_identifiers()

回傳包含表中符號之名稱的視圖物件 (view object)。請參閱視圖物件的文件

lookup(name)

在表中查找 name 並回傳一個 Symbol 實例。

get_symbols()

回傳表中名稱的 Symbol 實例串列。

get_children()

回傳巢狀符號表的串列。

class symtable.Function

一個函式或方法的命名空間。該類別繼承自 SymbolTable

get_parameters()

回傳一個包含此函式參數名稱的元組 (tuple)。

get_locals()

回傳一個包含此函式中區域變數 (locals) 名稱的元組。

get_globals()

回傳一個包含此函式中全域變數 (globals) 名稱的元組。

get_nonlocals()

回傳一個包含此函式中明確宣告的非區域變數 (nonlocals) 名稱的元組。

get_frees()

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

class symtable.Class

一個類別的命名空間。該類別繼承自 SymbolTable

get_methods()

回傳一個包含類別中聲明的類似方法之函式名稱的元組。

在這裡,術語「方法 (method)」表示透過 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() 會在 runtime 引發 TypeError,但 A.f 仍然被視為類似方法的函式。

Deprecated since version 3.14, will be removed in version 3.16.

class symtable.Symbol

SymbolTable 中的條目對應於來源中的識別器。建構函式不是公開的。

get_name()

回傳符號的名稱。

is_referenced()

如果該符號在其區塊中使用,則回傳 True

is_imported()

如果符號是從 import 陳述式建立的,則回傳 True

is_parameter()

如果符號是一個參數,則回傳 True

is_type_parameter()

Return True if the symbol is a type parameter.

在 3.14 版被加入.

is_global()

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

is_nonlocal()

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

is_declared_global()

如果使用全域陳述式將符號聲明為全域的,則回傳 True

is_local()

如果符號是其區塊的區域符號,則回傳 True

is_annotated()

如果符號有被註釋,則回傳 True

在 3.6 版被加入.

is_free()

如果該符號在其區塊中被參照 (referenced) 但未被賦值 (assigned),則回傳 True

is_free_class()

Return True if a class-scoped symbol is free from the perspective of a method.

Consider the following example:

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

In this example, the class-scoped symbol x is considered to be free from the perspective of C.method, thereby allowing the latter to return 1 at runtime and not 2.

在 3.14 版被加入.

is_assigned()

如果該符號被賦值到其區塊中,則回傳 True

is_comp_iter()

Return True if the symbol is a comprehension iteration variable.

在 3.14 版被加入.

is_comp_cell()

Return True if the symbol is a cell in an inlined comprehension.

在 3.14 版被加入.

is_namespace()

如果名稱綁定引入 (introduce) 新的命名空間,則回傳 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 原始檔產生符號表並轉儲 (dump) 到 stdout。如果未指定輸入檔案,則從 stdin 讀取內容。