LINUX.ORG.RU

Подтвердите баг в CPython

 


0

3

Следующий код:

def x(key):
    def y():
        print key
        if callable(key):
            key = key()
    y()
x(0)
вызывает исключение
UnboundLocalError: local variable 'key' referenced before assignment

хотя, если закомментировать строчку key = key() (и вставить pass), этот код, как и положено, напечатает на экране ноль.

// CPython 2.7.2



Последнее исправление: justluke (всего исправлений: 3)

Подтверждаю.

$ python --version
Python 2.7.3rc2

Не уверен, что это бага. С питоном вообще не знаком, так что не имею ни малейшего понятия, корректен код, или нет.

DELIRIUM ☆☆☆☆☆
()

Подтверждаю, сабмить.

theos ★★★
()
Ответ на: комментарий от anonymous

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name.

unless a contained block introduces a different binding for the name

Фирштейн?

anonymous
()
Ответ на: комментарий от encyrtid

Почему?

Потому что это описанное поведение. Выше привел цитату из Language Reference.

anonymous
()
Ответ на: комментарий от encyrtid

А почему функция y() должна знать аргумент key, если этот key функции не передается? ЕМНИП нужно в y() определять key, как глобальную переменную.

siphonops ★★★
()
Ответ на: комментарий от encyrtid

Т.е. в питоне нельзя присвоить значение замкнутой переменной?

Это вообще не относится к проблеме ТС. Но да, нельзя.

Здесь, при определении переменной, она сразу ограничивается текущей областью видимости, поэтому «key» из родительского блока не виден.

anonymous
()

Это не баг. Есть новый кейворд для таких кейзов в третьей ветке:

def x(key):
    def y():
        nonlocal key
        print(key)
        if callable(key):
            key = key()
    y()
x(0)

zz ★★★★
()

Где же у вас баг? Всё в порядке. Передайте key функции y, и всё будет работать. Локальная переменная ограничена областью видимости той функции, в которой она была объявлена. Это не баг, а фича языка. Очень логичное поведение, которое уберегает от всяких нежданчиков.

lucentcode ★★★★★
()

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

Deleted
()
Ответ на: комментарий от tailgunner

Или минимальный пример, воспроизводящий «баг».

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

Deleted
()
Ответ на: комментарий от Deleted

человек столкнулся с корректным ограничением на запрашиваемый алгоритмический вывих.

Причем тут «вывихи»? Это известный wart Питона, мешает работать, официально признан и исправлен.

tailgunner ★★★★★
()
def x(key):
    def y():
        print key
        if callable(key):
            globals()[filter(lambda x: x[1] == key, globals().iteritems())[0][0]] = key()
    y()
aedeph_ ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.