Учим Python от Нины Захаренко
Изменить эту страницу
Область внутри функции
Внутри функции в Python изменяется область .
Подумайте об этом так: область видимости в Python происходит с помощью пробелов. Когда мы выделяем код, содержащийся в функции, путем отступа под определением функции, его область действия заменяется на новой внутренней областью. Он имеет доступ к переменным, определенным вне его, но не может их изменить.
Когда функция завершает работу, ее область видимости исчезает, как и ее определенные переменные.
Давайте еще раз проверим это в REPL:
>>> def twitter_info(): ... twitter_account = "ння" ... print(f"Учетная запись внутри функции: {twitter_account}") ... >>> twitter_info() Учетная запись внутри функции: nnja >>> print(f"Учетная запись вне функции: {twitter_account}") Traceback (последний последний вызов): Файл "", строка 1, в NameError: имя «twitter_account» не определено
Мы получаем NameError
при попытке доступа к переменной twitter_account
вне функции. Это потому, что это выходит за рамки, как мы и ожидали.
Использование переменных, определенных вне функции
Обычно мы хотим быть осторожными при использовании переменных, определенных вне нашей функции.
Обратите внимание, что если мы попытаемся изменить значение переменной, определенной вне нашей функции, мы увидим изменения в самой функции, но не вне ее.
Вы не можете изменять переменные, определенные вне функции внутри функции. Если вы попытаетесь это сделать, ваши изменения будут применяться только во время работы функции. Как только функция завершает работу, значение возвращается к тому, что было до запуска вашей функции.
Немного запутанно, но давайте посмотрим на это в действии:
>>> name = "Nina" >>> print(f"Имя вне функции: {имя}") Имя вне функции: Нина >>> >>> определение try_change_name(): ... имя = "Макс" ... print(f"Имя внутри функции: {имя}") ... > >> try_change_name() Имя внутри функции: Max >>> print(f"Имя вне функции: {имя}") Имя вне функции: Нина
Если бы мы не знали, что искать, программа могла бы вести себя не так, как мы ожидали. Хорошее эмпирическое правило — четко называть наши переменные и свести к минимуму количество переменных, которые мы объявляем вне функций и классов, о чем вы узнаете во второй день.
Уместно использовать константу, переменную, определенную заглавными буквами, со словами, разделенными символами подчеркивания. Константа — это значение, которое мы ожидаем использовать несколько раз в нашей программе, но никогда не ожидаем его изменения программным путем.
Например:
>>> ROOT_API_URL = "https://api.github.com" >>> def api_search_repos_url(): ... вернуть f"{ROOT_API_URL}/поиск/репозитории" ... >>> api_search_repos_url() 'https://api.github.com/search/repositories' >>>
Область действия функции Python — Темы масштабирования
Обзор
Область действия определяется как «степень области или предмета, с которым что-то связано или к которому это относится» . В мире кодирования это определение остается тем же и для переменных. Как правило, переменная действительна только в блоке, в котором она создана, и называется ее областью действия. Переменная «область действия» — очень фундаментальная концепция в программировании. Каждый разработчик знает о локальной и глобальной области видимости переменной, независимо от своего рабочего языка. Чаще всего разработчики знают о двух общих областях:
- Глобальная: имя, определенное в этой области, доступно для всего вашего кода
- Local: имя, определенное в этой области, доступно только для блока, в котором оно было объявлено, т. е. в его локальном блоке. Однако, когда дело доходит до Python, все немного по-другому.
Scope
- В этой статье мы изучим области видимости переменных в Python.
- Мы узнаем о локальных, закрытых, глобальных и встроенных областях в Python, то есть ( LEGB в Python).
Введение
Прежде чем понять, что такое области видимости в Python, нам необходимо ознакомиться с пространствами имен и их отличиями от областей видимости. Давайте кратко обсудим их:
Согласно официальной документации Python:
- Пространство имен определяет, какие идентификаторы (переменные, классы, функции и т. д.) доступны для использования.
- Область действия — это текстовая область программы Python, в которой непосредственно доступно пространство имен.
Давайте копнем немного глубже:
Когда вы объявляете переменную, python отслеживает ее «имя» и «значение», создавая объект и добавляя этот объект во внутренний словарь. Этот внутренний словарь служит механизмом поиска для Python. Когда вы пытаетесь получить доступ к переменной, интерпретатор Python просматривает ее имя в этом внутреннем словаре и возвращает ее значение, если оно найдено. Если не найдено, возвращает ошибку.
a = 1 # пространство имен {a: 1} # a теперь существует в пространстве имен напечатать (а) # 1 # b еще не существует в пространстве имен print(b) # => NameError: имя b не определено б = 16 # b теперь существует в пространстве имен печать (б) # 16
Следовательно, объекты этого словаря точно такие же, как пространства имен.
Но во время работы программы на Python в этот момент существует несколько пространств имен. Из этих пространств имен конкретные пространства имен, к которым у вас будет доступ, определяются областью действия, в которой вы находитесь.Следовательно, вернемся к определению области в соответствии с официальной документацией Python:
«Область — это текстовая область программы Python, в которой пространство имен доступно напрямую»
На простом языке область — это область в программа, которая решает, к каким конкретным пространствам имен (из всех существующих в данный момент пространств имен) у вас будет доступ.
Типы области действия Python и правило LEGB
Оказывается, в Python есть четыре типа области действия: LEGB => Local-Enclosed-Global-BuiltIn, и правило LEGB определяет порядок области , в котором интерпретатор просматривает для получения имени и значения переменной из
В Python, когда вы пытаетесь прочитать переменную, интерпретатор python извлечет соответствующую переменную, просматривая последовательно в порядке областей LEGB, то есть первое вхождение этой переменной, найденное в любой из областей, начиная с последовательно from, Local -> Enclosed -> Global -> BuiltIn, будет возвращен
Давайте разберемся, что такое каждая область видимости в Python. Примечание. Каждая область в последовательности LEGB менее специфична, чем предыдущая.Локальная область : локальная область определяется тем, где была определена переменная. Например: если переменная была определена внутри функции, то ее локальная область действия будет определена только как блок этой функции, тогда как если переменная была определена на верхнем уровне, то она будет рассматриваться в глобальной области видимости (поясняется ниже).
Пример 1 –
def func(): b = "Я люблю интервьюБит" print(b) # напечатает строку, хранящуюся в переменной b функция() print(b) # будет выброшено nameError, так как b существует только в локальной области видимости функции func()
Результат:
Я люблю интервьюБит Traceback (последний последний вызов): Файл «main.py», строка 6, вprint(b) # будет выброшено nameError, так как b существует в локальной области видимости функции func()’ NameError: имя «b» не определено
Поскольку b никогда не определялся на верхнем уровне (глобальном), он доступен только в локальной области видимости func(). Он возвращает ошибку при доступе за пределами области, в которой он никогда не был определен
- Закрытая область : также известная как нелокальная область, которую можно наблюдать, когда вы вкладываете функции в другие функции. Допустим, функция func1() имеет переменную a и вложенную функцию func2(). Для этой вложенной функции «func2()» «a» не является ни глобальной, ни локальной. Следовательно, область действия переменной «a» внутри функции «func2()» такая же, как и вложенная область, то есть ни глобальная, ни локальная, поэтому она также известна как нелокальная область 9.0057
Пример 2 –
def func1(): а = 10 определение функции2(): печать (а) функция2() функция1()
Вывод:
- Мысль-1 : Но что, если в примере 2 мы переназначим переменную «a» как 20 в «func2()»? Останется ли его значение прежним в области видимости func1()? Держитесь за эту мысль, так как мы вернемся к ней через некоторое время. Обратите внимание, что функция func2() никогда не существовала в своей локальной области видимости. Следовательно, согласно правилу LEGB, он не нашел «a» в области L, но нашел ее в области E, т. е. Enclosed Scope*
- Глобальная область действия : (также известная как область действия модуля), когда вы начинаете писать свой код на Python, вы находитесь в глобальной области действия. Основная глобальная область видимости — это пространство имен, на которое она указывает, когда вы начинаете писать свой код Python. Примечание: когда вы определяете имя в верхней части вашего модуля Python, это имя является глобальным только для этого конкретного модуля; именно поэтому его также называют модулем области
Пример 3 –
а = 10 определение функции1(): print("inside func1 ", a) # поскольку a не существует в локальной области видимости func1(), согласно правилу LEGB, интерпретатор заглянул в глобальную область видимости функция1() print("в локальном глобальном масштабе", а)
Выход:
внутри func1 10 в глобальном масштабе 10
- Thought-2 : Но что, если в примере 3 мы переназначим переменную «a» как 20 в «func1()»? Останется ли его значение прежним в глобальном масштабе? Держитесь за эту мысль, так как мы вернемся к ней через некоторое время. Обратите внимание, что переменная «a» не существует в локальной области видимости «func1()», поэтому, согласно правилу LEGB, она не находит «a» в L (LEGB), а не в E (LEGB). ), но находит его в «G», т.е. Global.
- Встроенная область : когда интерпретатор Python не может найти переменную в локальной, закрытой и глобальной области, он, наконец, ищет встроенную область. Мы импортируем «пи» из математической библиотеки в следующем примере. Этот импортированный «пи» будет принадлежать встроенной области видимости. Обратите внимание, что этот идентификатор не должен переопределяться, так как тогда он будет доступен интерпретатору Python для извлечения из локальной, закрытой или глобальной области (в зависимости от того, где он был переопределен)
Пример 4 —
из math import pi определение функции1(): print('внутри func1', пи) пи = 10 ''' не делайте этого, он переопределит встроенный идентификатор, так как тогда встроенное значение не будет прочитано, а будет прочитано переопределенное значение ''' print('в глобальном масштабе', pi) функция1()
Вывод:
в глобальном масштабе 3. 141592653589793 внутри func1 3.141592653589793
Примечание: скажем, если бы число пи было переопределено как «10», т. е. «пи = 10» на глобальном уровне, то интерпретатор Python всегда возвращал бы число пи как 10. Потому что сейчас оно было бы доступно не на L или E, но G, то есть глобальная область в соответствии с областью действия LEGB. И, следовательно, B, то есть встроенная область, никогда бы не рассматривалась.
Возвращаясь к мыслям, которые у нас были:
Мысль-1 : Но что, если в примере 2 мы переназначим переменную «a» как 20 в «func2()»? Останется ли его значение прежним в области видимости func1()?
- Что ж, в примере 2 при переназначении переменной «a» как 20 в «func2()»: Python создаст имя и значение в своем внутреннем словаре, так что «a» будет доступно для области видимости func2 как 20 , т.е. он определит «a» в локальной области видимости « func2 ()». Это означает, что для ‘func2()’ ‘a’ будет существовать как в локальной области, так и в закрытой области, но поскольку Local идет первым по порядку в правиле порядка LEGB, он будет извлекать значение из ‘a’, определенного в этой области. .
- Повторная демонстрация примера 2 с новыми операторами печати:
Пример 5 –
def func1(): а = 10 определение функции2(): а = 20 печать('функция2', а) функция2() печать('функция1', а) функция1()
Выход:
функция2 20 функция1 10
- Мы наблюдаем, что при обновлении «a» до 20 «a» переопределяется в локальной области видимости «func2()», и это то, что интерпретатор python сначала читает для «func2()», тогда как значение ‘a’ остается равным 10 в области видимости func1().
- Но что, если мы хотим: «a» при обновлении в «func2()» также обновлялось в области «func1()»?
- Здесь мы введем ключевое слово «нелокальный».
ключевое слово nonlocal
Ключевое слово nonlocal используется для работы в сценариях, где у нас есть вложенные функции. Используя ключевое слово nonlocal, мы сообщаем переменной, что она не должна принадлежать внутренней функции. Давайте разберем это на примере:
Добавление ключевого слова «нелокальный» в примере 5:
Пример 6 –
def func1(): а = 10 определение функции2(): нелокальный а печать('функция2', а) функция2() печать('функция1', а) функция1()
Выход:
функция2 20 функция1 20
При сравнении выходных данных примера 5 и примера 6 ясно видно, что при добавлении ключевого слова nonlocal изменения, внесенные в ‘a’ в ‘func2()’, отражаются в ‘func1()’ также. Почему это? Потому что «нелокальный» указывает «а», что он не принадлежит «func2()», а принадлежит «func1()». Следовательно, область видимости переменной ‘a’ остается нетронутой в func2().
Мысль-2 : Но что, если в примере 3 мы переназначим переменную «a» как 20 в «func1()»?
- Эта ситуация аналогична той, что мы наблюдали для ключевого слова «нелокальный».
- В примере 3, если мы переопределим «a» как 20 в «func1()», то ясно, что это переопределит «a» в локальной области видимости «func1()».
- Затем, в соответствии с правилом порядка LEGB, он будет действовать только в локальной области видимости «a» в «func1()».
- Давайте посмотрим на пример. Добавление «a = 20» в «func1()» в примере 3:
Пример 7 –
а = 10 определение функции1(): а = 20 print("inside func1 ", a) # поскольку a не существует в локальной области видимости func1(), согласно правилу LEGB, интерпретатор заглянул в глобальную область видимости печать("глобальный-1", а) функция1() печать("глобальный-2", а)
Выход –
глобальный 10 функция1 20 глобальный 10
- Мы можем заметить, что при присвоении «а» значения 20 «а» переопределяется в локальной области видимости «func1()».
- В соответствии с правилом LEGB, хотя «а» может существовать в глобальной области, но поскольку «а» также существует в локальной области «func1()», оно будет считывать значение в локальной области.
- Здесь мы введем ключевое слово «глобальное».
ключевое слово global
Глобальное ключевое слово — это ключевое слово, которое позволяет пользователю изменять переменную за пределами текущей области. Он используется внутри функции, когда мы хотим выполнять присваивания или когда мы хотим изменить значение переменной. Подобно ключевому слову nonlocal, оно указывает переменной, что она принадлежит глобальной области видимости, а не какой-либо другой области видимости. Обратите внимание, что ключевое слово nonlocal относится только к функциям и внутренним функциям, но для управления областью действия глобальной переменной внутри функции необходимо использовать ключевое слово global.
Добавление ключевого слова global в пример 7
Пример 8
a = 10 определение функции1(): глобальный а = 20 print("inside func1 ", a) # поскольку a не существует в локальной области видимости func1(), согласно правилу LEGB, интерпретатор заглянул в глобальную область видимости печать("глобальный-1", а) функция1() печать("глобальный-2", а)
Выход –
глобальный-1 10 функция1 20 глобальный-2 20
При сравнении вывода примера 7 и примера 8 видно, что при добавлении ключевого слова «global» изменения, внесенные в «a» в «func1()», отражаются глобально, поскольку теперь «a» существует только в глобальном масштабе. Почему это? Поскольку ключевое слово «global» указывает «a», что оно не принадлежит какой-либо функции, а существует глобально, следовательно, глобальная область видимости переменной «a» остается неизменной в «func1()», а также при использовании ключевого слова «global».
Заключение
- LEGB расшифровывается как Local-Enclosed-Global-BuiltIn, где эти 4 — это разные типы области видимости в Python.
- Локальная область в python переменной действительна только в функции/блоке, в котором она была определена.
- Закрытая область в python, также известная как нелокальная область действия переменной, допустима в случаях вложенных функций. Переменная в локальной области считается находящейся в закрытой области для вложенной функции.
- Переменная, объявленная вне всех функций или на верхнем уровне и доступная для всех блоков и функций, считается находящейся в Global Scope в python.