symtable
— 訪問編譯器的符號表¶
原始碼: Lib/symtable.py
符號表由編譯器在生成位元組碼之前從 AST 生成。符號表負責計算程式碼中每個識別符號的作用域。symtable
提供了一個介面來檢查這些表。
生成符號表¶
- symtable.symtable(code, filename, compile_type)¶
返回 Python 原始碼 code 的頂級
SymbolTable
。filename 是包含程式碼的檔名。compile_type 類似於compile()
的 mode 引數。
檢查符號表¶
- class symtable.SymbolTableType¶
一個列舉,指示
SymbolTable
物件的型別。- MODULE = "module"¶
用於模組的符號表。
- FUNCTION = "function"¶
用於函式的符號表。
- CLASS = "class"¶
用於類的符號表。
以下成員指的是不同型別的標註作用域。
- ANNOTATION = "annotation"¶
當
from __future__ import annotations
處於活動狀態時,用於標註。
- 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_children()¶
返回巢狀符號表的列表。
- class symtable.Function¶
函式或方法的名稱空間。此類繼承自
SymbolTable
。- get_parameters()¶
返回一個元組,其中包含此函式的引數名稱。
- get_locals()¶
返回一個元組,其中包含此函式中的區域性變數名稱。
- get_globals()¶
返回一個元組,其中包含此函式中的全域性變數名稱。
- get_nonlocals()¶
返回一個元組,其中包含此函式中顯式宣告的非區域性變數名稱。
- class symtable.Class¶
一個類的名稱空間。此類繼承自
SymbolTable
。- get_methods()¶
返回一個元組,其中包含在類中透過
def
或async def
宣告的方法式函式的名稱。在這裡,“方法”一詞指代透過
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
。在 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
在此示例中,類作用域符號
x
從C.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 原始檔生成符號表並轉儲到標準輸出。如果未指定輸入檔案,則從標準輸入讀取內容。