Функции области видимости питон

Область видимости в Python

Вы, наверное, не раз слышали термин область видимости, когда изучали программирование. Это весьма важная тема, незнание которой может привести к достаточно запутанным ошибкам. Область видимости указывает интерпретатору, когда наименование (или переменная) видимо. Другими словами, область видимости определяет, когда и где вы можете использовать свои переменные, функции, и т.д. Если вы попытаетесь использовать что-либо, что не является в вашей области видимости, вы получите ошибку NameError.

Python содержит три разных типа области видимости:

  • Локальная область видимости
  • Глобальная область видимости
  • Нелокальная область видимости (была добавлена в Python 3)

Локальная область видимости

Локальная область видимости наиболее часто используется в Python. Когда мы создаем переменную в блоке кода, она будет разрешена при помощи ближайшей области видимости, или областей. Группирование всех этих областей известно как среда блоков кода. Другими словами, все назначения выполняются в локальной области по умолчанию. Если вам нужно что-то другое, тогда вам нужно настроить свою переменную на глобальную или нелокальную область, которые мы рассмотрим немного позже. Сейчас мы создадим простой пример, используя интерпретатор Python, в котором демонстрируется назначение локальной области видимости.

Источник

Все, что вы хотели узнать про области видимости в Python, но стеснялись спросить

Сегодня мы будем говорить о важных теоретических основах, которые необходимо понимать и помнить, чтобы писать грамотный, читаемый и красивый код. Мы будем вести речь об областях видимости переменных. Эта статья будет полезна не только новичкам, но и опытным программистам, которые пришли в Python из другого языка и хотят разобраться с его механиками работы.

Читайте также:  Python целые числа диапазон

Области видимости определяют, в какой части программы мы можем работать с той или иной переменной, а от каких переменная «скрыта». Крайне важно понимать, как использовать только те значения и переменные, которые нам нужны, и как интерпретатор языка себя при этом ведет. А еще мы посмотрим, как обходить ограничения, накладываемые областями видимости на действия с переменными. В Python существует целых 3 области видимости:

Обычно, речь заходит про области видимости, когда происходит знакомство с функциями. На их примере мы и будем рассматривать работу областей видимости переменных.

Локальная область видимости

Рассмотрим функцию, которая выведет список some_list поэлементно:

def print_list(some_list): for element in some_list: print(element)

Здесь element и some_list – локальные переменные, которые видны только внутри функции, и которые не могут использоваться за ее пределами с теми значениями, которые были им присвоены внутри функции при ее работе. То есть, если мы в основном теле программы вызовем print(element) , то получим ошибку:

NameError: name 'element' is not defined

Теперь мы поступим следующим образом:

def print_list(some_list): for element in some_list: print(element) element = 'q' print_list([1, 2, 3]) print(element) 

Здесь переменная element внутри функции и переменная с таким же именем вне ее – это две разные переменные, их значения не перекрещиваются и не взаимозаменяются. Они называются одинаково, но ссылаются на разные объекты в памяти. Более того, переменная с именем element внутри функции живет столько же, сколько выполняется функция и не больше. Но будьте аккуратны с тем, чтобы давать локальным и глобальным переменным одинаковые имена, сейчас покажу почему:

def print_list(some_list): for element in sudden_list: print(element) sudden_list = [0, 0, 0] print_list([1, 2, 3])

Обратите внимание на то, что интерпретатор не указал нам на ошибки. А все потому что sudden_list находится в глобальной области видимости, то есть изнутри функции print_list мы можем к нему обращаться, поскольку изнутри видно то, что происходит снаружи. По причине таких механик работы старайтесь называть локальные переменные внутри функции не так, как называете переменные в глобальной области видимости.

Здесь важно поговорить о константах. Интерпретатору Python нет разницы как вы называете переменную, поэтому код выше будет лучше переписать в следующем виде:

SUDDEN_LIST = [0, 0, 0] def print_list(some_list): for element in SUDDEN_LIST: print(element) print_list([1, 2, 3]) 

Теперь все на своих местах. Дело в том, что в Python нельзя каким-то образом строго определить константу, как объект, который не должен быть изменен. Так что то, как вы используете значение переменной, имя которой записано заглавными буквами, остается лишь на вашей совести. Другой вопрос, что таким способом записанная переменная даст понять тому, кто будет читать ваш код, что переменная нигде изменяться не будет. Или по крайней мере не должна.

Глобальная область видимости

В Python есть ключевое слово global , которое позволяет изменять изнутри функции значение глобальной переменной. Оно записывается перед именем переменной, которая дальше внутри функции будет считаться глобальной. Как видно из примера, теперь значение переменной candy увеличивается, и обратите внимание на то, что мы не передаем ее в качестве аргумента функции get_candy() .

candy = 5 def get_candy(): global candy candy += 1 print('У меня <> конфет.'.format(candy)) get_candy() get_candy() print(candy)
 У меня 6 конфет. У меня 7 конфет. 7 

Однако менять значение глобальной переменной изнутри функции – не лучшая практика и лучше так не делать, поскольку читаемости кода это не способствует. Чем меньше то, что происходит внутри функции будет зависеть от глобальной области видимости, тем лучше.

Лайфхак: Чтобы не мучиться с именованием переменных, вы можете вынести основной код программы в функцию main() , тогда все переменные, которые будут объявлены внутри этой функции останутся локальными и не будут портить глобальную область видимости, увеличивая вероятность допустить ошибку.

Нелокальная область видимости

Появилось это понятие в Python 3 вместе с ключевым словом nonlocal . Логика его написания примерно такая же, как и у global . Однако у nonlocal есть особенность. Nonlocal используется чаще всего во вложенных функциях, когда мы хотим дать интерпретатору понять, что для вложенной функции определенная переменная не является локальной, но она и не является глобальной в общем смысле.

def get_candy(): candy = 5 def increment_candy(): nonlocal candy candy += 1 return candy return increment_candy result = get_candy()() print('Всего <> конфет.'.format(result))

Насколько это полезно вам предстоит решить самостоятельно. Больше примеров вы можете найти здесь.

В качестве вывода можно сформулировать несколько правил:

  1. Изнутри функции видны переменные, которые были определены и внутри нее и снаружи. Переменные, определенные внутри – локальные, снаружи – глобальные.
  2. Снаружи функций не видны никакие переменные, определенные внутри них.
  3. Изнутри функции можно изменять значение переменных, которые определены в глобальной области видимости с помощью спецификатора global .
  4. Изнутри вложенной функции с помощью спецификатора nonlocal можно изменять значения переменных, которые были определены во внешней функции, но не находятся в глобальной области видимости.

Также хочу пригласить всех желающих на бесплатный вебинар от OTUS, где изучим такой инструмент, как аннотация типов в Python: обсудим причины, по которым его многие недооценивают, рассмотрим ряд примеров из боевой практики, когда аннотация типов могла спасти или спасла ситуацию. Поговорим о том, как и когда внедрять проверку типов на своих проектах.

Источник

Область видимости

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

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

Для создания переменных, обладающих локальной областью видимости, необходимо всего лишь поместить их в отдельный блок кода, изолированный от остальной программы. Чтобы увидеть локальную переменную в действии, достаточно инициализировать целочисленный объект с именем x и значением 100 в функции f, как это сделано в следующем примере:

Здесь x имеет локальную область видимости, так как доступна лишь в рамках своей функции f. Вызывая данную функцию из внешней части программы, можно увидеть вывод целочисленного значения на экране. Однако, если попытаться вывести переменную x при помощи метода print вне зоны действия функции f, компилятор тут же выдаст ошибку:

def f(): x = 100 print(x) f() print(x) # 100 # Traceback (most recent call last): # File "main.py", line 5, in # print(x) # NameError: name 'x' is not defined 

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

Глобальные переменные

Чтобы иметь возможность использовать некоторое значение в любой части программы, следует объявить глобальную переменную. Для этого понадобиться создать переменную отдельно от области кода, ограниченной определенным блоком кода, например, функцией. В следующем примере демонстрируется идентификация целочисленного типа данных под названием x, который позже выводится на экран при помощи метода print в функции f:

x = 100 def f(): print(x) f() print(x) # 100 # 100 

Как можно заметить из результатов выполнения программы, значение 100 воспроизводится не только через f, но и с помощью обычного print. Таким образом, получение доступа к x осуществляется из любой части кода, благодаря глобальной области видимости подобного объекта. Но что будет, если попытаться изменить значение глобальной переменной в некой функции? Результаты такого эксперимента представлены в следующем фрагменте кода:

x = 100 def f(): x = 200 f() print(x) # 100 

Функция f присваивает значение 200 переменной с именем x, однако, вопреки ожиданиям, внешний метод print выводит число 100, которое принадлежало x изначально. Происходит так потому, что в данной программе создаются два разных объекта x с локальной, а также глобальной областью видимости. Исправить ситуацию поможет ключевое слово global :

x = 100 def f(): global x x = 200 f() print(x) # 200 

Пометив переменную x как global , можно обращаться к ее изначальному значению, которое было определено вне зоны действия функции f. Теперь после того как в x поместили число 200, вызов метода print выводит вполне ожидаемый результат, то есть измененное значение.

В Python глобальные переменные можно использовать для хранения каких то настроек программы или разрабатываемого модуля. Для этого хорошо подойдут словари. Но все таки не стоит злоупотреблять. Зачастую гораздо правильнее передавать в функции необходимые значения в качестве аргуменов, а если нужно перезаписать какое-то глобальное значение, то возвращать его из функции.

def my_abs(val): return -val if val  0 else val x = -15 x = my_abs(x) 

Нелокальные переменные

Итак, для обращения к глобальной переменной внутри функции f необходимо использовать ключевое слово global перед ее идентификатором. Но что если требуется вызывать совсем не глобальную, а переменную, которая была определена во внешнем методе, являясь при этом локальной для другого пространства имен, находящегося на уровень выше? Следующий код демонстрирует попытку взаимодействия со значением из внешней функции f1 в методе f2:

def f1(): x = 100 def f2(): x = 200 f2() print(x) f1() # 100 

Несмотря на то, что переменной с таким же именем x было присвоено новое значение 200, в результате выполнения написанных методов на экране отобразилось 100. Как и в том случае с двумя разными переменными, локальной и глобальной, здесь имеется также два различных объекта, которые идентифицированы в отдельных блоках кода. Чтобы обратиться к объекту, который не является локальным, необходимо воспользоваться модификатором nonlocal :

def f1(): x = 100 def f2(): nonlocal x x = 200 f2() print(x) f1() # 200 

Таким образом, в методе f2 осуществляется запись значения 200 в переменную x из функции f1. В результате подобных действий, вызов метода f1 из внешней части программы создает новую переменную x, значение которой меняется в f2 со 100 на 200 и выводится при помощи print.

python_school is maintained by avdosev. This page was generated by GitHub Pages.

Источник

Оцените статью