LINUX.ORG.RU

[Python] Локальные переменные

 


0

0

Уважаемый ЛОР, подскажи, пожалуйста, где подробно почитать про управление локальными переменными в Python. А то для меня это какая-то таинственная загадка. Например, в сырце ниже я тупо не понимаю, где и как связываются переменные и как реализуется механизм замыканий.

Поэтому прошу объяснить, а лучше -- тыкнуть ссылкой в правильную доку. Заранее мерси.

http://www.everfall.com/paste/id.php?id=zkda9oxhi58x&v=1

★★★
Ответ на: комментарий от balodja

а если "i = 1" удалить, то оно вот так ругается
File "local_test.py", line 4, in <lambda>
f = lambda: i
NameError: free variable 'i' referenced before assignment in enclosing scope

я так понимаю одинаковые отступы, это один локальный scope

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

Да это-то понятно. Я не представляю, как это все происходит "low level", как себе представлять вообще работу интерпретатора по части именно локальных переменных. Например, каким образом реализуется связывание переменных со их значением для работы механизма замыканий?

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

> я так понимаю одинаковые отступы, это один локальный scope

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

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

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

вендашколота иди учи уроки или к ег готовиться

dimon555 ★★★★★
()

Может вот так станет понятнее:

def myfunc():
    i = 0
    print 'myfunc:', id(i)
    def test():
        f = lambda: (i, id(i))
        i = 1
        print 'test1:', id(i)
        print f()
        i = 2
        print 'test2:', id(i)
        print f()
        return f
    f = test()
    i = 3
    print f()
myfunc()

mnt
()

Документация по Python 2.4.6, раздел 4.1, "Naming and binding":

"Names refer to objects. Names are introduced by name binding operations. Each occurrence of a name in the program text refers to the binding of that name established in the innermost function block containing the use.

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition.

...

The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment, for loop header, or in the second position of an except clause header".

Если по-простому, присваивание некоторому идентификатору в функции вызывает создание локальной для этой функции переменной с этим иденитифкатором (при отсуствии global). Заметь, что если во вложенной функции будет присваивание переменной с тем же идентификатором, то во вложенной функции бедт создана _новая_, локальная для вложенной функции переменная.

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

Угу, а более подбробно это как происходит? Вот есть у нас локальный словарь для имен и значений. Когда я использую во вложенной функции f имя i из test и при всем этом вызываю f внутри test, то оно берется из словаря функции test. А откуда же тогда берется значение i, когда я f вызываю снаружи от test, вернув f по return? Как происходит само это связывание?

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

> А откуда же тогда берется значение i, когда я f вызываю снаружи от test, вернув f по return?

Ну поисследуй атрибуты объекта "функция", если тебе интересно.

tailgunner ★★★★★
()
Ответ на: комментарий от val-amart

либастрал подсказывает вот что: может, вам не понятен порядок разрешения имен?
когда происходит обращение к переменной по имени (допустим, в некоей функции), то сначала происходит ее поиск в словаре этой функции, затем в словаре родительского обьекта, и так по иерархии аж до глобального пространства. если вас смущает вывод последнего print f() из внешней функции myfunc, то ты должен уяснить, что переменная i берется из словаря той функции, в которой она (функция f()) определена, т.е. из словаря функции test. это называется замыкания (http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BC%D1%8B%D0%BA%D0%B0%D0%BD%D0%B8...).

val-amart ★★★★★
()
Ответ на: комментарий от tailgunner

> Ну поисследуй атрибуты объекта "функция", если тебе интересно.

Весьма логичное решение, до которого я не догадался. Ключевая фраза "Cell type" слегка продвинула мое понимание. Мерси.

balodja ★★★
() автор топика
Ответ на: комментарий от val-amart

> когда происходит обращение к переменной по имени (допустим, в некоей функции), то сначала происходит ее поиск в словаре этой функции, затем в словаре родительского обьекта, и так по иерархии аж до глобального пространства.

Не совсем так, точнее совсем не так. Словаря всего два, в никаких родительских объектах никто ничего не ищет. Все гораздо сложнее.

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

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

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