Символ python может быть глобальным и локальным в одной и той же области видимости - PullRequest
1 голос
/ 05 апреля 2020

Рассмотрим эту функцию:

def content(path):
  global file # not useful but valid
  with open(path) as file:
    return file.read()

При создании таблицы символов (с использованием модуля symtable) и проверке символа file в области действия функции content, он является глобальным и локальным в то же время. После вызова этой функции глобальное имя file привязывается к объекту файла. Поэтому мне интересно, почему символ file в области действия функции также рассматривается как локальный символ?

Вот код для воспроизведения поведения (поместите его в файл, например с именем global_and_local.py):

import symtable

def content(path):
  global file
  with open(path) as file:
    return file.read()

symtable_root = symtable.symtable(content(__file__), __file__, "exec")
symtable_function = symtable_root.get_children()[0]
symbol_file = symtable_function.lookup('file')
print("symbol 'file' in function scope: is_global() =", symbol_file.is_global())
print("symbol 'file' in function scope: is_local() =", symbol_file.is_local())
print("global scope: file =", file)

Создается следующий вывод:

symbol 'file' in function scope: is_global() = True
symbol 'file' in function scope: is_local() = True
global scope: file = <_io.TextIOWrapper name='global_and_local.py' ...>

1 Ответ

3 голосов
/ 05 апреля 2020

По какой-то причине symtable определяет is_local как проверку того, происходят ли какие-либо операции привязки для символа в области (или аннотации, которые объединяются вместе с аннотированными назначениями на данном этапе) :

def is_local(self):
    return bool(self.__flags & DEF_BOUND)

, а не проверка, является ли символ на самом деле локальным, что выглядело бы как

def is_local(self):
    return bool(self.__scope in (LOCAL, CELL))

Я не уверен почему. Это может быть ошибкой. Я не думаю, что подобные модули получат широкое применение - потребовалось более года , прежде чем кто-нибудь заметил , что добавление оператора // сломало старый модуль parser, поэтому я мог легко увидеть, что это происходит незамеченным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...