Подтвердить что ты не робот

Странное поведение python с смешиванием глобальных переменных/параметров и функции с именем "top"

Следующий код (не непосредственно в интерпретаторе, а исполняемый как файл)

def top(deck):
    pass

def b():
    global deck

вызывает ошибку

SyntaxError: name 'deck' is local and global

на python2.6.4 и

SyntaxError: name 'deck' is parameter and global

на python 3.1

python2.4, похоже, принимает этот код, а также интерактивный интерпретатор 2.6.4.

Это уже нечетно; почему "колода" конфликтует, если она глобальна в одном методе и параметр в другом?

Но он становится более странным. Переименуйте 'top' в основном что-нибудь еще, и проблема исчезнет.

Может кто-нибудь объяснить это поведение? Я чувствую, что мне не хватает чего-то очень очевидного здесь. Является ли название "верх" каким-то образом влияющим на определенные области видимости?

Обновление

Это действительно является ошибкой в ​​ядре python. Я опубликовал отчет об ошибке.

4b9b3361

Ответ 1

Похоже, что это ошибка в обработке таблиц символов. Python/symtable.c имеет некоторый код, который (хотя и несколько запутанный) действительно рассматривает "верхний" как специальный идентификатор:

if (!GET_IDENTIFIER(top) ||
    !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0)) {
    PySymtable_Free(st);
    return NULL;
}

несколько позже:

if (name == GET_IDENTIFIER(top))
    st->st_global = st->st_cur->ste_symbols;

Далее в файле есть макрос:

#define GET_IDENTIFIER(VAR) \
    ((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))

который использует препроцессор C для инициализации переменной top для интернированной строки с именем переменной.

Я думаю, что в таблице символов должно использоваться имя "верх", чтобы ссылаться на код верхнего уровня, но почему он не использует то, что не может конфликтовать с реальной переменной, о которой я понятия не имею.

Я бы назвал это ошибкой, если бы я был вами.