Таблица символов в Python - PullRequest
10 голосов
/ 31 января 2012

Как мы можем увидеть таблицу символов исходного кода Python?

Я имею в виду, Python создает таблицу символов для каждой программы перед ее фактическим запуском.Итак, мой вопрос: как я могу получить эту таблицу символов в качестве вывода?

Ответы [ 4 ]

9 голосов
/ 31 января 2012

Python является динамическим, а не статичным по своей природе.Вместо таблицы символов, как в скомпилированном объектном коде, виртуальная машина имеет адресное пространство имен для ваших переменных.

Функция dir() или dir(module) возвращает эффективное пространство имен в этой точке кода.Он в основном используется в интерактивном интерпретаторе, но также может использоваться и кодом.Он возвращает список строк, каждая из которых является переменной с некоторым значением.

Функция globals() возвращает словарь имен переменных для значений переменных, где имена переменных в настоящий момент считаются глобальными в области видимости..

Функция locals() возвращает словарь имен переменных в значения переменных, где имена переменных считаются локальными в области действия в тот момент.

$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> import base64
>>> dir(base64)
['EMPTYSTRING', 'MAXBINSIZE', 'MAXLINESIZE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_b32alphabet', '_b32rev', '_b32tab', '_translate', '_translation', '_x', 'b16decode', 'b16encode', 'b32decode', 'b32encode', 'b64decode', 'b64encode', 'binascii', 'decode', 'decodestring', 'encode', 'encodestring', 'k', 're', 'standard_b64decode', 'standard_b64encode', 'struct', 'test', 'test1', 'urlsafe_b64decode', 'urlsafe_b64encode', 'v']
6 голосов
/ 31 января 2012

Если вы спрашиваете о таблице символов, которая используется при генерации байт-кода, взгляните на модуль symtable. Кроме того, эти две статьи Эли Бендерского являются захватывающими и очень подробными:

Внутренние элементы Python: таблицы символов, часть 1

Внутренние элементы Python: таблицы символов, часть 2

Во второй части он подробно описывает функцию, которая может распечатать описание symtable, но, похоже, она была написана для Python 3. Вот версия для Python 2.x:

def describe_symtable(st, recursive=True, indent=0):
    def print_d(s, *args):
            prefix = ' ' *indent
            print prefix + s + ' ' + ' '.join(args)

    print_d('Symtable: type=%s, id=%s, name=%s' % (
            st.get_type(), st.get_id(), st.get_name()))
    print_d('  nested:', str(st.is_nested()))
    print_d('  has children:', str(st.has_children()))
    print_d('  identifiers:', str(list(st.get_identifiers())))

    if recursive:
            for child_st in st.get_children():
                    describe_symtable(child_st, recursive, indent + 5)
5 голосов
/ 31 января 2012

Python не создает таблицу символов перед выполнением программы. Фактически, типы и функции могут быть (и обычно) определены во время выполнения.

Вас может заинтересовать чтение Зачем компилировать код Python?

Также смотрите подробный ответ от @ wberry

2 голосов
/ 31 января 2012

Вам, вероятно, понравится рецензия Эли Бендерского на тему здесь

В CPython у вас есть доступный модуль symtable.

В part 2 , Eli описывает метод, который обходит невероятно полезную таблицу символов:

def describe_symtable(st, recursive=True, indent=0):
    def print_d(s, *args):
        prefix = ' ' * indent
        print(prefix + s, *args)

    assert isinstance(st, symtable.SymbolTable)
    print_d('Symtable: type=%s, id=%s, name=%s' % (
                st.get_type(), st.get_id(), st.get_name()))
    print_d('  nested:', st.is_nested())
    print_d('  has children:', st.has_children())
    print_d('  identifiers:', list(st.get_identifiers()))

    if recursive:
        for child_st in st.get_children():
            describe_symtable(child_st, recursive, indent + 5)
...