|
||||||||||||||||||||||||
Область видимости в Python
Время создания: 29.07.2019 23:51
Текстовые метки: Python, python-scripts.com, Область видимости
Раздел: Разные закладки - Python - python-scripts.com
Запись: xintrea/mytetra_db_adgaver_new/master/base/1516450616jb1h8a2khb/text.html на raw.githubusercontent.com
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
Вы, наверное, не раз слышали термин область видимости , когда изучали программирование. Это весьма важная тема, незнание которой может привести к достаточно запутанным ошибкам. Область видимости указывает интерпретатору, когда наименование (или переменная) видимо. Другими словами, область видимости определяет, когда и где вы можете использовать свои переменные, функции , и т.д. Если вы попытаетесь использовать что-либо, что не является в вашей области видимости, вы получите ошибку NameError . Python содержит три разных типа области видимости:
Локальная область видимости Локальная область видимости наиболее часто используется в Python. Когда мы создаем переменную в блоке кода, она будет разрешена при помощи ближайшей области видимости, или областей. Группирование всех этих областей известно как среда блоков кода. Другими словами, все назначения выполняются в локальной области по умолчанию. Если вам нужно что-то другое, тогда вам нужно настроить свою переменную на глобальную или нелокальную область, которые мы рассмотрим немного позже. Сейчас мы создадим простой пример, используя интерпретатор Python, в котором демонстрируется назначение локальной области видимости. Результат
Здесь мы создаем переменную х и очень простую функцию , которая принимает два аргумента. Далее она выводит х и z. Обратите внимание на то, что мы не определили z, так что когда мы вызываем функцию, мы получаем ошибку NameError . Это происходит в связи с тем, что z не определена, или находится вне области видимости. Если вы определите z перед вызовом функции, тогда она будет найдена и ошибка NameError не возникнет. Ошибка NameError также возникает при попытке получения доступа к переменной, которая находится только внутри функции: Переменная i определена только внутри функции, так что при запуске кода мы получаем ошибку NameError. Давайте немного модифицируем первый пример. Разместим данный код в python-файл и попытаемся его запустить:
Нет, не выдаст. Причина в том, что мы имеем две переменные х. Переменная х внутри my_func имеет локальную область видимости функции и переопределяет переменную х вне функции. Так что когда мы вызываем функцию my_func, в выдаче мы видим 5, а не 10. Затем, когда функция возвращается, переменная х внутри функции my_func является кучей мусора и область для выдачи х срабатывает еще один раз. По этой причине последний оператор выдачи выдает именно 10. Если вы хотите кое-что поинтереснее, вы можете попытаться вывести х перед тем как назначить его в нашей функции: Кода вы запустите этот код, вы получите ошибку:
Это происходит потому, что Python замечает, что вы назначаете х в функцию my_func позже, что и приводит к ошибке, так как х еще не определен. Глобальная область видимости Python содержит оператор global. Это ключевое слово Python. Оператор global объявляет переменную доступной для блока кода, следующим за оператором. Хотя вы и можете создать наименование, перед тем, как объявить его глобальным, я настоятельно не рекомендую этого делать. Давайте попробуем использовать глобальную область для исправления нашей ошибке из предыдущего примера: Выдача данного кода должна быть следующей: Объявляя х как глобальный, мы говорим Python использовать первое объявление х для нашего первого оператора вывода в функции. Далее мы даем х новое значение – а именно 5, и выводим его еще раз, перед тем как выйти из функции. Обратите внимание на то, что х становится глобальной переменной , когда мы доходим до последнего оператора вывода в конце кода, и там х все еще равен 5. Давайте смешаем глобальную и локальную область видимости и поглядим, что из этого получится: Здесь мы назначаем с в качестве глобальной переменной. Таким образом, «с» будет выводиться и внутри и снаружи нашей функции. Мы также меняем местами значения переменных а и b в функции, чтобы показать, что мы можем переназначить их внутри функции, не меняя их вне функции. Это показывает, что переменные а и b не являются глобальными. Если вы запустите этот код, вы увидите следующую выдачу: Я хочу обратить ваше внимание на то, что не нужно менять глобальные переменные внутри функции. Комьюнити Python объявило такую практику очень нежелательной, так как из-за этого исправление кода становится намного сложнее. Теперь, с пониманием основных принципов локальных и глобальных областей, мы можем перейти к нелокальной области non_local . Область nonlocal В Python 3 было добавлено новое ключевое слово под названием nonlocal. С его помощью мы можем добавлять переопределение области во внутреннюю область. Вы можете ознакомиться со всей необходимой на данный счет информацией в PEP 3104. Это наглядно демонстрируется в нескольких примерах. Один из самых простых – это создание функции , которая может увеличиваться: Если вы попробуете запустить этот код, вы получите ошибку UnboundLocalError , так как переменная num ссылается прежде, чем она будет назначена в самой внутренней функции. Давайте добавим nonlocal в наш код: Результат работы:
Теперь наша возрастающая функция работает именно так, как мы от нее и ожидаем. Для заметки, тип такой функции называется closure (дословно – закрытие). Такая функция является блоком кода, который «закрывает» переменные nonlocal. Суть в том, что вы можете ссылать переменные, которые определены вне вашей функции. Обычно, nonlocal позволяет вам назначать переменные во внешней области, но не в глобальной. Так что вы не можете использовать nonlocal в функции подсчета, так как в таком случае она попытается передать функцию глобальной области. Попробуйте, и получите ошибку SyntaxError незамедлительно. Вместо этого, вам нужно использовать nonlocal во вложенной функции. Подведем итоги В данной статье мы смогли понять то, как переменная ссылается, используя ключевые слова Python global и nonlocal. Мы узнали, где мы можем их использовать и зачем. Мы также узнали кое-что о локальной области видимости. Хорошего дня и продолжайте экспериментировать! |
||||||||||||||||||||||||
Так же в этом разделе:
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
|