symtable --- دسترسی به جدول‌های نماد کامپایلر

کد منبع: Lib/symtable.py


جدول‌های نماد توسط کامپایلر از روی AST، درست پیش از تولید بایت‌کد، تولید می‌شوند. جدول نمادها وظیفه‌ی محاسبه‌ی محدوده‌ی هر شناسه در کد را دارد. symtable رابطی برای بررسی این جدول‌ها فراهم می‌کند.

تولید جدول‌های نماد

symtable.symtable(code, filename, compile_type)

SymbolTable سطح بالا را برای کد منبع پایتون code برمی‌گرداند. filename نام پرونده‌ای است که حاوی کد است. compile_type مانند آرگومان mode برای compile() است.

بررسی جدول‌های نماد

class symtable.SymbolTableType

شمارشی که نوع یک شیء SymbolTable را نشان می‌دهد.

MODULE = "module"

برای جدول نمادهای یک ماژول استفاده می‌شود.

FUNCTION = "function"

برای جدول نمادهای یک تابع استفاده می‌شود.

CLASS = "class"

برای جدول نمادهای یک کلاس استفاده می‌شود.

اعضای زیر به انواع مختلفی از annotation scopes اشاره دارند.

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

نام جدول را برمی‌گرداند. اگر جدول برای یک کلاس باشد، این نام، نام کلاس است؛ اگر جدول برای یک تابع باشد، نام تابع است؛ یا اگر جدول سراسری باشد، 'top' است (get_type() مقدار 'module' را برمی‌گرداند). برای محدوده‌های پارامتر نوع (که برای کلاس‌های عام، توابع عام و نام‌های مستعار نوع عام استفاده می‌شوند)، این نام، نام کلاس، تابع یا نام مستعار نوع زیربنایی است. برای محدوده‌های نام مستعار نوع، این نام، نامِ نام مستعار نوع است. برای محدوده‌های کران TypeVar، این نام، نام TypeVar است.

get_lineno()

شماره‌ی نخستین خط در بلوکی که این جدول آن را نشان می‌دهد را برمی‌گرداند.

is_optimized()

اگر متغیرهای محلی در این جدول قابل بهینه‌سازی باشند، True برمی‌گرداند.

is_nested()

اگر بلوک یک کلاس یا تابع تودرتو باشد، True را برمی‌گرداند.

has_children()

اگر بلوک دارای فضای نام های تودرتو درون خود باشد، True را برمی‌گرداند. این فضای نامها را می‌توان با get_children() به دست آورد.

get_identifiers()

یک شیء نما (view object) را برمی‌گرداند که شامل نام‌های نمادهای جدول است. documentation of view objects را ببینید.

lookup(name)

جستجوی name در جدول و بازگرداندن یک نمونه از Symbol.

get_symbols()

فهرستی از نمونه‌های Symbol را برای نام‌های موجود در جدول برمی‌گرداند.

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

اگر نماد از یک دستور ایمپورت ایجاد شده باشد، 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()

اگر پیوند نام (name binding) یک فضای نام جدید ایجاد کند، True را برمی‌گرداند.

اگر از نام به‌عنوان هدف یک دستور تابع یا کلاس استفاده شود، این درست خواهد بود.

برای مثال:

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

توجه داشته باشید که یک نام واحد می‌تواند به چند شیء مقید شود. اگر نتیجه True باشد، آن نام ممکن است به اشیای دیگری نیز مقید شود، مانند یک عدد صحیح یا فهرست، که این موضوع فضای نام جدیدی را معرفی نمی‌کند.

get_namespaces()

فهرستی از فضای نام های مقیدشده به این نام را برمی‌گرداند.

get_namespace()

فضای نام مقیدشده به این نام را برمی‌گرداند. اگر بیش از یک فضای نام به این نام متصل باشد یا هیچ فضای نامی به این نام مقید نباشد، یک ValueError پرتاب می‌شود.

استفاده از خط فرمان

اضافه شده در نسخه‌ی 3.13.

ماژول symtable را می‌توان به‌عنوان یک اسکریپت از خط فرمان اجرا کرد.

python -m symtable [infile...]

جدول‌های نماد برای پرونده‌های منبع پایتون مشخص‌شده تولید می‌شوند و در stdout ریخته می‌شوند. اگر هیچ پرونده ورودی مشخص نشده باشد، محتوا از stdin خوانده می‌شود.