Главная страница
Навигация по странице:

  • Закрепление пройденного Контрольные вопросы

  • Основы видимости имен в языке Python

  • Разрешение имен: правило LEGB Если предыдущий раздел показался вам запутанным, спешу успокоить – в действительности все сводится к трем простым правилам. Для инструкции def:•

  • Встроенная область видимости (Python) Глобальная область видимости (модуль)

  • Локальные области видимости объемлющих функций

  • Пример области видимости

  • Математический анализ. 3е издание


    Скачать 4.86 Mb.
    Название3е издание
    АнкорМатематический анализ
    Дата04.02.2022
    Размер4.86 Mb.
    Формат файлаpdf
    Имя файлаpython_01.pdf
    ТипДокументы
    #351981
    страница48 из 98
    1   ...   44   45   46   47   48   49   50   51   ...   98
    396
    Глава 15. Основы функций
    Почти все имена в функции intersect являются локальными перемен
    ными:

    Переменная res явно участвует в операции присваивания, поэтому она – локальная переменная.

    Аргументы передаются через операцию присваивания, поэтому seq1
    и seq2 тоже локальные переменные.

    Цикл for присваивает элементы переменной, поэтому имя x также является локальным.
    Все эти локальные переменные появляются только в момент вызова функции и исчезают, когда функция возвращает управление – инст
    рукция return, стоящая в конце функции intersect, возвращает объ+
    ект
    результата, а имя res исчезает. Однако, чтобы полностью исследо
    вать понятие локальности, нам необходимо перейти к главе 16.
    В заключение
    В этой главе были представлены основные идеи, на которых основано определение функции, – синтаксис и принцип действия инструкций def и return, выражений вызова функций, а также суть и преимущест
    ва полиморфизма в функциях языка Python. Как было показано, инст
    рукция def – это исполняемый программный код, который создает объект функции. Когда позднее производится вызов функции, переда
    ча объектов производится за счет выполнения операции присваивания
    (вспомните, в главе 6 говорилось, что присваивание в языке Python оз
    начает передачу ссылок на объекты, которые фактически реализова
    ны в виде указателей), а вычисленные значения возвращаются обрат
    но с помощью инструкции return. В этой главе мы также приступили к изучению таких понятий, как локальные переменные и области ви
    димости, но более подробно эти темы будут рассматриваться в главе
    16. Сначала всетаки ответьте на контрольные вопросы.
    Закрепление пройденного
    Контрольные вопросы
    1. Какие преимущества несет использование функций?
    2. В какой момент времени интерпретатор Python создает функции?
    3. Что возвращает функция, если в ней отсутствует инструкция return?
    4. Когда выполняется программный код, вложенный в инструкцию определения функции?
    5. Почему нежелательно выполнять проверку типов объектов, переда
    ваемых функции?

    Закрепление пройденного
    397
    Ответы
    1. Функции представляют собой основной способ избежать избыточ
    ности программного кода – выделение программного кода в виде функции означает, что в будущем нам потребуется изменить един
    ственную копию действующего кода. Кроме того, функции – это ос
    новные блоки программного кода многократного пользования – за
    ключение программного кода в функции превращает его в инстру
    мент многократного пользования, который может вызываться раз
    личными программами. Наконец, функции позволяют разбить сложную систему на небольшие и легко управляемые части, каж
    дая из которых может разрабатываться отдельно.
    2. Функция создается, когда интерпретатор достигает инструкции def и выполняет ее; эта инструкция создает объект функции и свя
    зывает его с именем функции. Обычно это происходит, когда файл модуля, включающего функцию, импортируется другим модулем
    (вспомните, что во время импорта программный код файла выпол
    няется от начала до конца, включая и инструкции def), но это мо
    жет происходить, когда инструкция def вводится в интерактивной оболочке или во время выполнения вложенного блока другой инст
    рукции, такой как if.
    3. Когда поток управления достигает конца тела функции, не встре
    тив на своем пути инструкцию return, по умолчанию функция воз
    вращает объект None. Такие функции обычно вызываются как инст
    рукции выражений, так как присваивание объекта None перемен
    ной в целом бессмысленно.
    4. Тело функции (программный код, вложенный в инструкцию опре
    деления функции) выполняется, когда позднее производится вызов функции. Тело функции выполняется всякий раз, когда происхо
    дит вызов.
    5. Проверка типов объектов, передаваемых функции, – это надежный способ ограничить их гибкость, потому что в этом случае функция сможет работать только с объектами определенных типов. Без та
    кой проверки функция наверняка сможет обрабатывать целую ка
    тегорию типов объектов – любые объекты, поддерживающие интер
    фейс, ожидаемый функцией, смогут быть обработаны. (Термин ин+
    терфейс
    означает набор методов и операций, которые используют
    ся функцией.)

    16
    Области видимости и аргументы
    В главе 15 были описаны основы определения и вызова функций. Как мы видели, базовая модель функций в языке Python достаточно проста в использовании. В этой главе будут представлены подробности, лежа
    щие в основе областей видимости – мест, где определяются перемен
    ные и где выполняется их поиск, – и механизма передачи аргумен+
    тов
    – способа передачи объектов в функции.
    Правила видимости
    Теперь, когда вы готовы приступить к созданию своих собственных функций, нам необходимо более формально определить, что означают имена в языке Python. Всякий раз, когда в программе используется некоторое имя, интерпретатор создает, изменяет или отыскивает это имя в пространстве имен – в области, где находятся имена. Когда мы говорим о поиске значения имени применительно к программному ко
    ду, под термином область видимости подразумевается пространство имен: т. е. место в программном коде, где имени было присвоено зна
    чение, определяет область видимости этого имени для программного кода.
    Практически все, что имеет отношение к именам, включая классифи
    кацию областей видимости, в языке Python связано с операциями при
    сваивания. Как мы уже видели, имена появляются в тот момент, когда им впервые присваиваются некоторые значения, и прежде чем имена смогут быть использованы, им необходимо присвоить значения. По
    скольку имена не объявляются заранее, интерпретатор Python по ме
    стоположению операции присваивания связывает имя с конкретным пространством имен. Другими словами, место, где выполняется при

    Правила видимости
    399
    сваивание, определяет пространство имен, в котором будет находиться имя, а, следовательно, и область его видимости.
    Помимо упаковки программного кода функции привносят в програм
    мы еще один слой пространства имен – по умолчанию все имена, зна
    чения которым присваиваются внутри функции, ассоциируются с про
    странством имен этой функции и никак иначе. Это означает, что:

    Имена, определяемые внутри инструкции def, видны только про
    граммному коду внутри инструкции def. К этим именам нельзя об
    ратиться за пределами функции.

    Имена, определяемые внутри инструкции def, не вступают в кон
    фликт с именами, находящимися за пределами инструкции def, да
    же если и там и там присутствуют одинаковые имена. Имя X, кото
    рому присвоено значение за пределами данной инструкции def (на
    пример, в другой инструкции def или на верхнем уровне модуля)
    полностью отлично от имени X, которому присвоено значение внут
    ри инструкции def.
    В любом случае область видимости переменной (где она может исполь
    зоваться) всегда определяется местом, где ей было присвоено значение,
    и никакого отношения не имеет к месту, откуда была вызвана функ
    ция. Если присваивание переменной выполняется внутри инструкции def
    , переменная является локальной для этой функции; если присваи
    вание производится за пределами инструкции def, она является гло+
    бальной
    для всего файла. Мы называем это лексической областью ви+
    димости
    , потому что области видимости переменных целиком опреде
    ляются местоположением этих переменных в исходных текстах про
    граммы, а не местом, откуда вызываются функции.
    Например, в следующем файле модуля инструкция присваивания X = 99
    создает глобальную переменную с именем X (она видима из любого мес
    та в файле), а инструкция X = 88 создает локальную переменную X (она видима только внутри инструкции def):
    X = 99
    def func():
    X = 88
    Даже при том, что обе переменные имеют имя X, области видимости де
    лают их различными. Таким образом, области видимости функций по
    зволяют избежать конфликтов имен в программах и превращают функции в самостоятельные элементы программ.
    Основы видимости имен в языке Python
    До того как мы начали писать функции, весь программный код разме
    щался на верхнем уровне модуля (например, он не был вложен в инст
    рукции def), поэтому все имена, которые мы использовали, либо нахо

    400
    Глава 16. Области видимости и аргументы дились на верхнем уровне в модуле, либо относились к предопределен
    ным именам языка Python (например, open).
    1
    Функции образуют вло
    женные пространства имен (области видимости), которые ограничивают доступ к используемым в них именам, благодаря чему имена внутри функций не вступают в конфликт с именами за их пределами (внутри модуля или внутри других функций). Повторю еще раз, функции обра
    зуют локальную область видимости, а модули – глобальную. Эти две области взаимосвязаны между собой следующим образом:

    Объемлющий модуль – это глобальная область видимости. Каж
    дый модуль – это глобальная область видимости, т. е. пространство имен, в котором создаются переменные на верхнем уровне в файле модуля. Глобальные переменные для внешнего мира становятся ат
    рибутами объекта модуля, но внутри модуля могут использоваться как простые переменные.

    Глобальная область видимости охватывает единственный файл.
    Не надо заблуждаться насчет слова «глобальный» – имена на верх
    нем уровне файла являются глобальными только для программного кода в этом файле. На самом деле в языке Python не существует та
    кого понятия, как всеобъемлющая глобальная для всех файлов об
    ласть видимости. Имена всегда относятся к какомунибудь модулю и всегда необходимо явно импортировать модуль, чтобы иметь воз
    можность использовать имена, определяемые в нем. Когда вы слы
    шите слово «глобальный», подразумевайте «модуль».

    Каждый вызов функции создает новую локальную область види!
    мости. Всякий раз, когда вызывается функция, создается новая ло
    кальная область видимости – т. е. пространство имен, в котором на
    ходятся имена, определяемые внутри функции. Каждую инструк
    цию def (и выражение lambda) можно представить себе как определе
    ние новой локальной области видимости. Но так как язык Python позволяет функциям вызывать самих себя в цикле (этот прием из
    вестен как рекурсия), локальная область видимости с технической точки зрения соответствует вызову функции – другими словами,
    каждый вызов создает новое локальное пространство имен. Рекур
    сию удобно использовать, когда выполняется обработка данных,
    структура которых заранее неизвестна.

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

    Правила видимости
    401
    него уровня в модуле, который вмещает функцию, это имя необхо
    димо объявить внутри функции глобальным с помощью инструк
    ции global.

    Все остальные имена являются локальными в объемлющей облас!
    ти видимости, глобальными или встроенными. Предполагается,
    что имена, которым не присваивались значения внутри определе
    ния функции, находятся в объемлющей локальной области види
    мости (внутри объемлющей инструкции def), глобальной (в про
    странстве имен модуля) или встроенной (предопределенные имена в модуле __builtin__).
    Обратите внимание, что любые операции присваивания, выполняемые внутри функции, классифицируют имена как локальные: инструкция
    =
    , инструкция import, инструкция def, передача аргументов и т. д. Сле
    дует также заметить, что операции непосредственного изменения объ
    ектов не рассматривают имена как локальные – это свойственно толь
    ко операциям присваивания. Например, если имени L присвоен спи
    сок, определенный на верхнем уровне в модуле, то такая инструкция,
    как L.append(X), внутри функции не будет классифицировать имя L как локальное, тогда как инструкция L = X будет. В первом случае список L
    будет найден в глобальной области видимости и инструкция изменит глобальный список.
    Разрешение имен: правило LEGB
    Если предыдущий раздел показался вам запутанным, спешу успоко
    ить – в действительности все сводится к трем простым правилам. Для инструкции def:

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

    По умолчанию операция присваивания создает локальные имена.

    Глобальные объявления отображают имена на область видимости вмещающего модуля.
    Другими словами, все имена, которым присваиваются значения внут
    ри инструкции def (или внутри выражения lambda, с которым мы позна
    комимся позже), по умолчанию являются локальными; функции могут использовать имена в лексически (т. е., физически) объемлющих функ
    циях и в глобальной области видимости, но чтобы иметь возможность изменять их, они должны быть объявлены глобальными. Схема разре
    шения имен в языке Python иногда называется правилом LEGB, назва
    ние которого состоит из первых букв названий областей видимости:

    Когда внутри функции выполняется обращение к неизвестному имени, интерпретатор пытается отыскать его в четырех областях видимости – в локальной (local, L), затем в локальной области лю
    бой объемлющей инструкции def (enclosing, E) или в выражении

    402
    Глава 16. Области видимости и аргументы lambda
    , затем в глобальной (global, G) и, наконец, во встроенной
    (builtin, B). Поиск завершается, как только будет найдено первое подходящее имя.

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

    Когда выполняется присваивание имени за пределами функции (т. е.
    на уровне модуля или в интерактивной оболочке), локальная область видимости совпадает с глобальной – с пространством имен модуля.
    На рис. 16.1 показаны четыре области видимости в языке Python. При
    мечательно, что второй области видимости E – в области видимости объемлющей инструкции def или выражения lambda, с технической точки зрения может находиться несколько вложенных друг в друга об
    ластей. Но они появляются, только когда имеются вложенные друг в друга функции.
    1 1
    В первом издании этой книги правило поиска в областях видимости было названо «правилом LGB». Уровень объемлющей инструкции def был добав
    лен в язык Python позднее, чтобы ликвидировать необходимость явной пе
    редачи объемлющей области видимости. Но эта тема едва ли представляет интерес для начинающих, поэтому мы рассмотрим ее позднее в этой главе.
    Рис. 16.1. Правило LEGB поиска имен в областях видимости.
    Когда производится обращение к переменной, интерпретатор Python
    начинает искать ее в следующее порядке: в локальной области видимости,
    во всех локальных областях видимости объемлющих функций, в глобальной
    области видимости и, наконец, во встроенной области видимости.
    Поиск завершается, как только будет найдено первое подходящее имя.
    Место, где в программном коде производится присваивание значения
    переменной, обычно определяет ее область видимости
    Имена, определяемые тем или иным способом внутри функции
    (инструкция def или lambda), которые не были объявлены как глобальные.
    Встроенная область видимости (Python)
    Глобальная область видимости (модуль)
    Предопределенные имена в модуле встроенных имен:
    open
    , range, SyntaxError…
    Имена, определяемые на верхнем уровне модуля или объявленные внутри инструкций def как глобальные.
    Локальные области видимости объемлющих функций
    Имена в локальной области видимости любой и всех объемлющих функций (инструкция def или lambda), изнутри наружу.
    Локальная область видимости (функция)

    Правила видимости
    403
    Кроме того, имейте в виду, что эти правила применяются только к про
    стым именам переменных (таким как spam). В пятой и шестой частях книги мы увидим, что полные имена атрибутов (такие как object.spam)
    принадлежат определенным объектам и к ним применяются иные пра
    вила поиска, отличные от правил поиска в областях видимости, кото
    рые мы только что рассмотрели. При обращении к атрибутам (имя, сле
    дующее за точкой) поиск производится в одном или более объектах, а не в областях видимости, что связано с механизмом, который называется
    «наследованием» (рассматривается в шестой части книги).
    Пример области видимости
    Рассмотрим более крупный пример, демонстрирующий суть областей видимости. Предположим, что следующий фрагмент составляет содер
    жимое файла модуля:
    # Глобальная область видимости
    X = 99 # X и func определены в модуле: глобальная область
    def func(Y): # Y и Z определены в функции: локальная область
    # Локальная область видимости
    Z = X + Y # X – глобальная переменная
    return Z
    func(1) # func в модуле: result=100
    В этом примере функция и модуль используют в своей работе несколь
    ко имен. Применяя правила области видимости языка Python, можно классифицировать эти имена следующим образом:
    Глобальные имена: X и func
    X
    – это глобальное имя, так как она объявлена на верхнем уровне модуля. К ней можно обращаться внутри функции, не объявляя ее глобальной. func – это глобальное имя по тем же причинам. Инст
    рукция def связывает объект функции с именем func на верхнем уровне модуля.
    Локальные имена: Y и Z
    Имена Y и Z являются локальными (и существуют только во время выполнения функции), потому что присваивание значений обеим именам осуществляется внутри определения функции: присваива
    ние переменной Z производится с помощью инструкции =, а Y – пото
    му что аргументы всегда передаются через операцию присваивания.
    Суть такого разделения имен заключается в том, что локальные пере
    менные играют роль временных имен, которые необходимы только на время исполнения функции. Например, в предыдущем примере аргу
    мент Y и результат сложения Z существуют только внутри функции –
    эти имена не пересекаются с вмещающим пространством имен модуля
    (или с пространствами имен любых других функций).

    1   ...   44   45   46   47   48   49   50   51   ...   98


    написать администратору сайта