LINUX.ORG.RU

питон замыкания

 


0

4

Поясните мне логику питона. Функция x1() выводит 1, а x2() вообще падает с ошибкой reference before assigment. Получается что я из вложенной функции имею только доступ на чтение к переменным «родительской» функции?

def x1():
    def y():
        z = 3
    z = 1
    y()
    print z

def x2():
    def y():
        print z
        z = 3
    z = 1
    y()
    print z

x1()
x2()
★★

нет тут замыканий

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

nonlocal z
Это то чего ты хочешь?

Видимо этого я и хочу, но в моем питоне 2.7.9 такого ключевого слова нет((

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

Ах да. Если бы ты написал:

def x2():
    def y():
        print z
    z = 1
    y()

Оно у тебя вывело 1. Но поскольку, у тебя внутри y() есть z=.. Оно считается локальный переменной заданной внутри scope, а ты пытаешься к ней обратиться до её объявления и получаешь ошибку. Так уж устроен scope в питон.

Вот по теме http://stackoverflow.com/questions/3190706/nonlocal-keyword-in-python-2-x

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

Видимо этого я и хочу, но в моем питоне 2.7.9 такого ключевого слова нет((

Сделай список как z = [1] и правь его элементы.

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

Обычно, когда не осиливаешь функциональное программирование, лучше вернуться к объектно-ориентированному, а не городить уродские костыли с контейнерами :-).

ei-grad ★★★★★
()
Ответ на: комментарий от mashina

Сделай список как z = [1] и правь его элементы.

А так работает, почему-то. Ввидимо с сылками на объекты питон оперирует по другому, но не со всеми, строку например, он тоже не изменил

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

Почитай про мутабельные и немутабельные переменные. В ссылке на so всё объяснено же

you can modify nonlocal variables. But you cannot do assignment to nonlocal variables. E.g., this will raise UnboundLocalError: def inner(): print d; d = {'y': 1}. Here, print d reads outer d thus creating nonlocal variable d in inner scope

pawnhearts ★★★★★
()
Ответ на: комментарий от ei-grad

Обычно, когда не осиливаешь функциональное программирование, лучше вернуться к объектно-ориентированному, а не городить уродские костыли с контейнерами :-).

Обычно лучше ничего не писать когда хочешь написать глупость.

mashina ★★★★★
()

Не делай так. В питоне подобные вещи принято делать по-другому, без замыканий. А если хочешь поиграться, выучи питон получше, чтобы не спрашивать базовые вещи. Потому что тебе тут насоветуют, и у тебя в голове винегрет будет, вместо четкого понимания, за которым нужно обращаться к учебникам и официальной документации.

Virtuos86 ★★★★★
()

Просто нужно прописать z = 0 перед этими def x1, def x2 функциями.

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

Я, немного, на грудь. Но Новый Год на носу, не вижу ничего предосудительного.

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

Затем что она там проблему не решает в том виде как в моем примере.

ei-grad ★★★★★
()

Ну и гадость же этот ваш заливной питон...

FRWHate
()

Как уже, наверняка, много раз пояснили, значение z присвоенное внутри y() в первом случае не передаётся наружу по причине того, что она локальная для функции y() (поведение в обычном C). Сама y() не возвращает какого-либо значения, а изменения её внутренних переменных не изменяет значений внешних, так как внутренняя переменная создаётся отдельно (по новому адресу) и не имеет отношение к внешней, пусть даже с таким же именем.

Во втором он просто ругается, что ты хочешь вывести на печать переменную, которой ещё не присвоил значение.

grem ★★★★★
()
def x1():
    def y():
        z[0]=3
    z=[1]
    y()
    print z[0]
    
x1()
3

результат пары запросов в гугле (чей-то блог).

Во втором случае, если хочешь получить в выводе «3», «1»:

def x2():
    def y():
        z=[3]
        print z[0]
    z=[1]
    y()
    print z[0]

grem ★★★★★
()
Последнее исправление: grem (всего исправлений: 4)
Ответ на: комментарий от grem

Факир был в доску и фокус не удался:

def x1():
    def y():
        z=3
        print z
    z=1
    y()
    print z
A1
()

Поясните мне логику питона

Логика такая: мы слишком тупые и сделали говноязык с кучей граблей, но так как мы слишком гордые, то мы сделаем вид, что так и задумано. Потом с умной рожей будем всем рассказывать как это гениально.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Сходи вызови gensym, gensym сам не вызовется.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.