Передача значений из объемлющей области видимости с помощью аргументов со значениями по умолчанию

peredacha znachenij iz obemljushhej oblasti vidimosti s pomoshhju argumentov so znacheniyami po umolchaniju Графические интерфейсы пользователя

Еще более тонкая проблема: обратите внимание, что если создание кнопки в этом примере будет выполняться внутри функции, а не на верхнем уровне сценария, имя X перестанет быть глобальным и окажется в локальной области видимости объемлющей функции. Может создаться ощущение, что переменная X исчезнет сразу после выхода из функции, еще до того, как возникнет событие, которое вызовет выполнение lambda-выражения:

def handler(A, B):

использование A и B

def makegui(): X = 42 Button(text=’ni’, command=(lambda: handler(X, ‘spam’))) # запоминает X

makegui()

mainloop() # в этой точке область видимости функции makegui прекратила # существование

К счастью, модель ссылок в объемлющую область видимости, реализованная в Python, автоматически сохранит значение X, находящееся в локальной области видимости объемлющей функции, где используется lambda-выражение, и обеспечит его доступность в обработчике, когда он будет вызван по событию нажатия кнопки. Обычно этот прием действует именно так, как нам хотелось бы, и автоматически обслуживает подобные ссылки на переменные.

Однако такое использование объемлющей области видимости можно сделать более явным, применив аргументы со значениями по умолчанию, которые также сохраняют значения переменных из локальной области видимости объемлющей функции после выхода из нее. Например, в следующем фрагменте аргумент с именем X (слева в выражении X=X) сохранит объект 42, потому что переменная с именем X (справа в выражении X=X) используется не только в объемлющей области видимости, но и в сгенерированной функции, которая позднее будет вызываться без аргументов:

def handler(A, B): # аргументы со значениями по умолчанию обеспечивают

…использование A и B # сохранение информации о состоянии

def makegui(): X = 42 Button(text=’ni’, command=(lambda X=X: handler(X, ‘spam’)))

Так как значения по умолчанию аргументов вычисляются и сохраняются на этапе выполнения инструкции lambda (а не на этапе вызова функции, сгенерированной этой инструкцией), они обеспечивают явный способ сохранения объектов, доступ к которым будет осуществляться уже в процессе обработки события. Позднее библиотека вызовет lambda-функцию без аргументов, поэтому все ее аргументы получат значения по умолчанию.

В оригинальной версии этого примера не было никаких проблем, потому что переменная X находилась в глобальной области видимости и потому была доступна функции, сгенерированной lambda-выражением. Однако при использовании внутри функции переменная X может исчезнуть после выхода из объемлющей функции.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий