Python Глобальные переменные
Переменные, созданные вне функции (как и во всех приведенных выше примерах), называются глобальными переменными.
Глобальные переменные могут использоваться всеми, как внутри функций, так и снаружи.
Пример
Создайте переменную вне функции и используйте ее внутри функции
def myfunc():
 print(«Python это » + x)
Если вы создадите переменную с тем же именем внутри функции, эта переменная будет локальной и может использоваться только внутри функции. Глобальная переменная с тем же именем останется прежней, глобальной и с исходным значением.
Пример
Создайте переменную внутри функции с тем же именем, что и у глобальной переменной.
def myfunc():
x = «фантастика»
print(«Python это » + x)
print(«Python это » + x)
Глобальное ключевое слово
Обычно, когда вы создаете переменную внутри функции, эта переменная является локальной и может использоваться только внутри этой функции.
Чтобы создать глобальную переменную внутри функции, вы можете использовать ключевое слово global .
Пример
Если вы используете ключевое слово global переменная принадлежит к глобальной области видимости:
def myfunc():
global x
x = «фантастика»
print(«Python это » + x)
Кроме того, используйте ключевое слово global если вы хотите изменить глобальную переменную внутри функции.
Пример
Чтобы изменить значение глобальной переменной внутри функции, обратитесь к переменной с помощью ключевого слова global :
def myfunc():
global x
x = «фантастика»
print(«Python это » + x)
Мы только что запустили
SchoolsW3 видео
ВЫБОР ЦВЕТА
курс сегодня!
Сообщить об ошибке
Если вы хотите сообщить об ошибке или внести предложение, не стесняйтесь отправлять на электронное письмо:
Ваше предложение:
Спасибо Вам за то, что помогаете!
Ваше сообщение было отправлено в SchoolsW3.
ТОП Учебники
ТОП Справочники
ТОП Примеры
Получить сертификат
SchoolsW3 оптимизирован для бесплатного обучения, проверки и подготовки знаний. Примеры в редакторе упрощают и улучшают чтение и базовое понимание. Учебники, ссылки, примеры постоянно пересматриваются, чтобы избежать ошибок, но не возможно гарантировать полную правильность всего содержания. Некоторые страницы сайта могут быть не переведены на РУССКИЙ язык, можно отправить страницу как ошибку, так же можете самостоятельно заняться переводом. Используя данный сайт, вы соглашаетесь прочитать и принять Условия к использованию, Cookies и политика конфиденциальности.
Локальные и глобальные переменные в Python
При программировании на Python, как и во всяком другом языке всегда крайне важно четко понимать сущность, отличия, нюансы применения и возможные последствия от использования переменных различных областей видимости. Ведь, по большому счету, от такого четкого понимания роли различных типов переменных в конечном счете зависит структура и логика наших программ в целом, то какие пользовательские классы, объекты и модули мы в этих программах сформируем.
В Python для переменных существует 4-ре следующие области видимости: локальная, нелокальная, глобальная и системная.
Системная область видимости шефствует над системными переменными из операционок ваших вычислительных средств и является наиболее универсальной, поскольку обеспечивает доступ к этим переменным из любого модуля или функции в ваших программах. В тоже время, переменные из данной области видимости относительно не часто используются в кодинге и, в основном применяются при разработке системных утилит или программ тесно связанных с возможностями операционных систем, в которых они выполняются.
Еще одной довольно специфической в применении является нелокальная область видимости, переменные которой используются главным образом во вложенных функциях тогда, когда необходимо указать, что для конкретной вложенной функции определенная переменная не является ни локальной, ни глобальной с точки зрения всей программы (модуля).
Таким образом, априори можно констатировать, что наиболее распространенными являются локальные и глобальные переменные, о нюансах применения которых пойдет речь далее в этой статье.
Определение локальных и глобальных переменных
Глобальной переменной называется та переменная, доступ к которой можно получить из любого места в коде вашего модуля – отдельного программного файла. Объявление этих переменных производится вне любых программных блоков типа функций, классов или процедур и, обычно помещается в начало файла с программным кодом.
Важно отметить, что программа на Python может состоят из нескольких отдельных программных файлов (нескольких модулей), но переменная будет являться глобальной лишь в том модули, в котором она была объявлена. Из других модулей, независимо от того являются ли они частями одной программы или нет, данная переменная видна не будет.
Локальной переменной может быть любая переменная, объявленная внутри какого-либо программного блока типа функции, класса, метода или процедуры. Основным отличием локальных переменных от глобальных является то, доступ к первым может осуществляться лишь в том программном блоке, в котором они были объявлены.
Чтение глобальных переменных
Давайте в самом начале нашей программы объявим переменную privetstviye , которую инициализируем строкой “Привет земляне!”:
>>> privetstviye = "Привет земляне!"
Затем, давайте объявим простенькую функцию prosmotr_privetstviya() , которая будет выводить на печать нашу раннее объявленную переменную privetstviye :
>>> def prosmotr_privetstviya(): . print(privetstviye) .
Как и следовало ожидать, в результате вызова вышеназванной функции мы увидим выведенную на дисплей строку “Привет земляне!”:
>>> prosmotr_privetstviya() Привет земляне!
Хотя переменная privetstviye в функции prosmotr_privetstviya() и не была объявлена, данная функция все-таки без проблем смогла ее вывести внутри себя. Это объясняется тем, что данную переменную мы объявили в глобальной области видимости — в начале программы и вне всяких программных блоков. Такое место объявления нашей переменной автоматически придало ей статус глобальной – видимой во всех программных блоках, имеющихся в данном модули (программном файле).
Изменение значений у локальных и глобальных переменных
Как мы уже знаем, всегда при объявлении переменных внутри каких-либо программных блоков, Python присваивает этим переменным статус локальных, то есть тех, которые являются доступными лишь внутри блока, где они были объявлены. Кроме того, те переменные, которые передаются пользовательским функциям в качестве аргументов, для самых этих функций также являются локальными.
На примерах раннее мы уже выяснили, что внутри программных блоков (функций) запросто можно использовать глобальные переменные для вывода их значений. Теперь же давайте выясним, можно ли внутри таких функций изменять значения глобальным переменным. Для этого объявим дополнительную пользовательскую функцию izmenyayemoye_privetstviya() , которая принимая в качестве своего аргумента utochneniye уточнение для приветствия, будет конкатенировать (объединять) его вместе со словом “Привет” и присваивать полученное значение нашей “якобы” глобальной переменной privetstviye из предыдущего раздела нашей статьи. В дополнение к этому вышеназванная функция буде еще и выводить получившиеся значение из переменной privetstviye на дисплей:
>>> def izmenyayemoye_privetstviya(utochneniye): . privetstviye = f"Привет utochneniye>!" . print(privetstviye) .
Как вы думаете, что нам выведет функция izmenyayemoye_privetstviya() с переданным, например, аргументом “инопланетяне”, а что покажет непосредственно сама переменная privetstviye , выведенная через стандартную функцию print(). Давайте для наглядности приведем полный листинг кода с этим примером:
privetstviye = "Привет земляне!" def izmenyayemoye_privetstviya(utochneniye): privetstviye = f"Привет utochneniye>!" print(privetstviye) izmenyayemoye_privetstviya("инопланетяне") print(privetstviye) # Привет инопланетяне! # Привет земляне!
Из приведенного выше примера четко видно, что в программах на Python вполне себе могут уживаться глобальные и локальные переменные имеющие одинаковые имена. Но, вот как раз по этой причине, Python не позволяет поменять значения у глобальных переменных внутри каких-либо программных блоков. Как только мы попытаемся это сделать внутри одного из таких блоков, наш любимый интерпретатор именно в этом блоке объявить дополнительную переменную с тем же именем, но не с глобальной, а с локальной областью видимости.
Затенение переменных
Итак, мы уже выяснили, что внутри каких-либо программных блоков значения, как глобальных, так и локальных переменных являются равнодоступными только для чтения. При этом, если у нас глобальная и локальная переменные имеют одинаковые имена и, мы попытаемся одну из этих переменных прочитать внутри какой-либо функции, класса или любого другого программного блока, то приоритет всегда будет отдан именно локальной переменной.
Если же внутри программного блока нам нужно не прочитать, а изменить значение какой-либо переменной, то даже когда данная переменная является у нас глобальной, мы фактически способны изменить (инициализировать) исключительно только локальную переменную.
Иногда в Python специально для оптимизации кода используют вышеописанные особенности сочетания одноименных глобальных и локальных переменных, а сам процесс создания этих переменных с одинаковыми именами называют затенением. Вмести с тем, следует отметить, что многие опытные разработчики все-таки не склонны применять практику затенения переменных поскольку видят в ней негативное влияние на читабельность и логику восприятия разрабатываемого ими кода.
Совместное использование локальных и глобальных переменных
Интуитивно, на уровне подсознание, мы где-то уже почти осознали то, что внутри любого программного блока априори не может быть двух переменных с одинаковыми именами, одна из которых трактовалась бы интерпретатором, как глобальная, а другая, как локальная переменная. Но, давайте посмотрим, как будет реагировать наш интерпретатор в случае реального наличия такой ситуации. Для этого немного изменим раннее объявленную нами функцию izmenyayemoye_privetstviya() таким образом, чтобы прежде она выводила бы на дисплей строку приветствия из нашей глобальной переменной privetstviye , а затем переменной с тем же именем присваивала бы другую строку приветствие сформированную с учетом значения, полученного из своего аргумента. В конце же данной функции мы снова попытаемся вывести уже измененное содержимое переменной privetstviye на дисплей.
>>> def izmenyayemoye_privetstviya(utochneniye): . print(privetstviye) . privetstviye = f"Привет utochneniye>!" . print(privetstviye) .
По идее можно было бы предположить, что в результате вызова только что откорректированной нами функции с аргументом:
izmenyayemoye_privetstviya("инопланетяне")
у нас на дисплее сначала выведется содержание нашей предварительно инициализированной глобальной переменной (Привет земляне!), а затем содержание нашей локальной переменной (Привет инопланетяне!), которая была инициализирована прямо внутри нашей функции. Но, на самом деле произойдет нечто иное:
privetstviye = "Привет земляне!" def izmenyayemoye_privetstviya(utochneniye): print(privetstviye) privetstviye = f"Привет utochneniye>!" print(privetstviye) izmenyayemoye_privetstviya("инопланетяне") # Traceback (most recent call last): # File "", line 8, in # File "", line 4, in izmenyayemoye_privetstviya # UnboundLocalError: cannot access local variable 'privetstviye' where it is not associated with a value
Фактически, при вызове первого print(privetstviye) в функции izmenyayemoye_privetstviya() мы в нашем примере получили исключение UnboundLocalError, гласящее о том, что локальная переменная privetstviye не может быть выведена на дисплей, так как она еще не инициализирована.
На первый взгляд данная ошибка может показаться несуразностью, ведь мы предварительно объявили и инициализировали privetstviye вне всяких программных блоков, как глобальную переменную. А тут, в ошибке выдается, что она якобы превратилась в локальную, да еще не инициализированную переменную? Но, на самом деле это объясняется тем, что, анализируя код нашей функции, интерпретатор Python прежде всего просматривает операторы присваивания и, только потом отслеживает имена переменных, которым в нашем случае мы присвоили одинаковые имена privetstviye. Именно поэтому, видя в нашей функции оператор присвоения в отношении к переменной privetstviye, интерпретатор не только априори объявляет эту переменную локальной, но и любое другое упоминание ее имени в функции также воспринимает в качестве этой же локальной переменной.
Таким образом, в 4-й строке программы вместе со стандартной функцией print() у нас используется локальная переменная privetstviye, которая фактически инициализируется только на следующей, 5-й строке.
В общем случае необходимо отметить, что любое присвоение внутри программного блока делает из одноименной глобальной переменной, локальную. Следовательно, если эта переменная упоминается в программном блоке прежде, чем она была инициализирована, то это вызовет ошибку.
Выводы
Из данной статьи в отношении интерпретатора Python можно сделать следующие обобщающие выводы:
- Использование значений глобальных переменных допускается в любом месте модуля (файла с программой), как внутри программных блоков (функций, классов, методов или процедур), так и вне их.
- Значения локальных переменных внутри тех программных блоков, где они были объявлены могут без ограничений, как использоваться, так и изменяться.
- В случае наличия в модули одноименных глобальных и локальных переменных, внутри программных блоков могут быть доступны лишь значения объявленных там локальных переменных. Этот процесс называется затенением переменных.
- Внутри программных блоков каждая переменная должна однозначно восприниматься интерпретатором, либо как локальная, либо как глобальная. Двух одноименных переменных с разными областями видимости в интерпретаторе быть не может.
- Оператор присвоения внутри программных блоков в случае одноименных глобальных и локальных переменных всегда глобальную переменную замещает локальной, что может привести к ошибки при использовании данной переменной до ее инициализации.
Локальные и глобальные переменные
В программировании особое внимание уделяется концепции о локальных и глобальных переменных, а также связанное с ними представление об областях видимости. Соответственно, локальные переменные видны только в локальной области видимости, которой может выступать отдельно взятая функция. Глобальные переменные видны во всей программе. «Видны» – значит, известны, доступны. К ним можно обратиться по имени и получить связанное с ними значение.
К глобальной переменной можно обратиться из локальной области видимости. К локальной переменной нельзя обратиться из глобальной области видимости, потому что локальная переменная существует только в момент выполнения тела функции. При выходе из нее, локальные переменные исчезают. Компьютерная память, которая под них отводилась, освобождается. Когда функция будет снова вызвана, локальные переменные будут созданы заново.
Вернемся к нашей программе из прошлого урока, немного упростив ее для удобства:
def rectangle(): a = float(input("Ширина: ")) b = float(input("Высота: ")) print("Площадь: %.2f" % (a * b)) def triangle(): a = float(input("Основание: ")) h = float(input("Высота: ")) print("Площадь: %.2f" % (0.5 * a * h)) figure = input("1-прямоугольник, 2-треугольник: ") if figure == '1': rectangle() elif figure == '2': triangle()
Сколько здесь переменных? Какие из них являются глобальными, а какие – локальными?
Здесь пять переменных. Глобальной является только figure . Переменные a и b из функции rectangle , а также a и h из triangle – локальные. При этом локальные переменные с одним и тем же идентификатором a , но объявленные в разных функциях, – разные переменные.
Следует отметить, что идентификаторы rectangle и triangle , хотя и не являются именами переменных, а представляют собой имена функций, также имеют область видимости. В данном случае она глобальная, так как функции объявлены непосредственно в основной ветке программы.
В приведенной программе к глобальной области видимости относятся заголовки объявлений функций, объявление и присваивание переменной figure , конструкция условного оператора.
К локальной области относятся тела функций. Если, находясь в глобальной области видимости, мы попытаемся обратиться к локальной переменной, то возникнет ошибка:
… elif figure == '2': triangle() print(a)
1-прямоугольник, 2-треугольник: 2 Основание: 4 Высота: 5 Площадь: 10.00 Traceback (most recent call last): File "test.py", line 17, in print(a) NameError: name 'a' is not defined
Однако мы можем обращаться из функций к глобальным переменным:
def rectangle(): a = float(input("Ширина %s: " % figure)) b = float(input("Высота %s: " % figure)) print("Площадь: %.2f" % (a * b)) def triangle(): a = float(input("Основание %s: " % figure)) h = float(input("Высота %s: " % figure)) print("Площадь: %.2f" % (0.5 * a * h)) figure = input("1-прямоугольник, 2-треугольник: ") if figure == '1': rectangle() elif figure == '2': triangle()
1-прямоугольник, 2-треугольник: 1 Ширина 1: 6.35 Высота 1: 2.75 Площадь: 17.46
В данном случае из тел функций происходит обращение к имени figure , которое, из-за того, что было объявлено в глобальной области видимости, видимо во всей программе.
Наши функции не совсем идеальны. Они должны вычислять площади фигур, но выводить результат на экран им не следовало бы. Вполне вероятна ситуация, когда результат нужен для внутренних нужд программы, для каких-то дальнейших вычислений, а выводить ли его на экран – вопрос второстепенный.
Если функции не будут выводить, а только вычислять результат, то его надо где-то сохранить для дальнейшего использования. Для этого подошли бы глобальные переменные. В них можно записать результат. Напишем программу вот так:
def rectangle(): a = float(input("Ширина: ")) b = float(input("Высота: ")) result = a * b def triangle(): a = float(input("Основание: ")) h = float(input("Высота: ")) result = 0.5 * a * h result = 0 figure = input("1-прямоугольник, 2-треугольник: ") if figure == '1': rectangle() elif figure == '2': triangle() print("Площадь: %.2f" % result)
Итак, мы ввели в программу глобальную переменную result и инициировали ее нулем. В функциях ей присваивается результат вычислений. В конце программы ее значение выводится на экран. Мы ожидаем, что программа будет прекрасно работать. Однако…
1-прямоугольник, 2-треугольник: 2 Основание: 6 Высота: 4.5 Площадь: 0.00
… что-то пошло не так.
Дело в том, что в Python присвоение значения переменной совмещено с ее объявлением. (Во многих других языках это не так.) Поэтому, когда имя result впервые упоминается в локальной области видимости, и при этом происходит присваивание ей значения, то создается локальная переменная result . Это другая переменная, никак не связанная с глобальной result .
Когда функция завершает свою работу, то значение локальной result теряется, а глобальная не была изменена.
Когда мы вызывали внутри функции переменную figure , то ничего ей не присваивали. Наоборот, мы запрашивали ее значение. Интерпретатор Питона искал ее значение сначала в локальной области видимости и не находил. После этого шел в глобальную и находил.
В случае с result он ничего не ищет. Он выполняет вычисления справа от знака присваивания, создает локальную переменную result , связывает ее с полученным значением.
На самом деле можно принудительно обратиться к глобальной переменной. Для этого существует команда global :
def rectangle(): a = float(input("Ширина: ")) b = float(input("Высота: ")) global result result = a * b def triangle(): a = float(input("Основание: ")) h = float(input("Высота: ")) global result result = 0.5 * a * h result = 0 figure = input("1-прямоугольник, 2-треугольник: ") if figure == '1': rectangle() elif figure == '2': triangle() print("Площадь: %.2f" % result)
В таком варианте программа будет работать правильно.
Однако менять значения глобальных переменных в теле функции – плохая практика. В больших программах трудно отследить, где, какая функция и почему изменила их значение. Программист смотрит на исходное значение глобальной переменной и может подумать, что оно остается таким же. Сложно заметить, что какая-то функция поменяла его. Подобное ведет к логическим ошибкам.
Чтобы избавиться от необходимости использовать глобальные переменные, для функций существует возможность возврата результата своей работы в основную ветку программы. И уже это полученное из функции значение можно присвоить глобальной переменной в глобальной области видимости. Это делает программу более понятной.
Как функция принимает и возвращает данные, будет рассмотрено в следующих уроках.
Практическая работа
В языке Python можно внутри одной функции определять другую. Напишите программу по следующему описанию.
В основной ветке программы вызывается функция cylinder() , которая вычисляет площадь цилиндра. В теле cylinder определена функция circle , вычисляющая площадь круга по формуле πr 2 . В теле cylinder у пользователя спрашивается, хочет ли он получить только площадь боковой поверхности цилиндра, которая вычисляется по формуле 2πrh, или полную площадь цилиндра. В последнем случае к площади боковой поверхности цилиндра должен добавляться удвоенный результат вычислений функции circle() .
Как вы думаете, можно ли из основной ветки программы вызвать функцию, вложенную в другую функцию? Почему?
Примеры решения и дополнительные уроки в pdf-версии курса
X Скрыть Наверх
Python. Введение в программирование
Область видимости
Область видимости переменных в языке программирования Python представляет собой некое пространство имен, в рамках которого функционируют созданные объекты. Эта особенность позволяет ограничивать доступ к определенным значениям во избежание конфликтов между одинаковыми идентификаторами. Переменные бывают двух видов: локальные и глобальные, что в большинстве случае определяется местом их первичной идентификации в программе.
Локальные переменные
Для создания переменных, обладающих локальной областью видимости, необходимо всего лишь поместить их в отдельный блок кода, изолированный от остальной программы. Чтобы увидеть локальную переменную в действии, достаточно инициализировать целочисленный объект с именем x и значением 100 в функции f, как это сделано в следующем примере:
def f(): x = 100 print(x) f() 100
Здесь 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 return val + 1 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.
Важно заметить, что конструкция nonlocal была добавлена только в 3-ей версии языка Python.
Видимость из загружаемого модуля
Теперь разберемся с видимостью глобальных переменных между загружаемыми модулями Python. Например, мы подключаем другой модуль с помощью команды import. Создадим файл «test.py» и в него запишем следующий код:
print('Загружается модуль test') x = 100 def f(): print('Из функции x=' + str(x))
То есть мы определили глобальную переменную x для модуля test. Так же определили функцию, которая выводит на экран её значение.
Теперь создадим файл main.py, который и будем запускать. В нем мы импортируем модуль test, а так же создадим свою глобальную переменную x. После этого выведем значения глобальной переменной из test, вызовим функцию f, а так же проверим, что значение переменной в модуле main не изменилось:
x = 200 print('Из модуля main x=' + str(x)) import test print('Из модуля test x=' + str(test.x)) print('Присваиваем значение 300') test.x = 300; print('Из модуля test x=' + str(test.x)) test.f() print('Из модуля main x=' + str(x)) Из модуля main x=200 Загружается модуль test Из модуля test x=100 Присваиваем значение 300 Из модуля test x=300 Из функции x=300 Из модуля main x=200
Мы в первой же строчке записали в x значение 200. Это было сделано, чтобы показать, что после того, как мы загрузим внешний модуль, значение этой переменной не изменится. Так и вышло. Обращаясь к переменной из загруженной библиотеки, удалось прочитать его и изменить значение.
Теперь модифицируем программу следующим образом:
x = 200 print('Из модуля main x=' + str(x)) from test import * f() print('Из модуля main x=' + str(x)) print('Присваиваем значение 300') x = 300 f() print('Из модуля main x=' + str(x)) Из модуля main x=200 Загружается модуль test Из функции x=100 Из модуля main x=100 Присваиваем значение 300 Из функции x=100 Из модуля main x=300
В этом случае для загрузки мы использовали команду «from test import *». Мы импортировали все переменные и функции. После загрузки модуля значение переменной x в модуле main изменилось. Но при вызове функции, мы получаем значение x из модуля test. После присвоения нового значения переменной x, значение, которое выводит функция f не изменяется.
Следует по возможности избегать подключение библиотек с помощью команды from библиотека import *, а подключать только необходимые функции — from библиотека import функция. При этом надо удостовериться, что эти имена не используются в основном модуле.
Использование import библиотека поможет избежать возможных ошибок, если в программе есть функции, классы и переменные с такими же наименованиями, как и в загружаемом модуле.
Глобальные переменные в классе
Точно так же как и в функциях, можно обращаться к глобальным переменным и в классе Python. Разберем пример:
x = 100 print(x) class c1: global x x = 200 def __init__(self): global x x = 300 def f(self): global x x = 400 print(x) o1 = c1() print(x) o1.f() print(x) 100 200 300 400
Мы объявили глобальную переменную x. Вывели значение переменной до и после объявления класса. Как видим значение изменилось. После того как мы создали объект класса, значение в очередной раз поменялось. Это произошло, потому что сработал конструктор класса — метод __init__. После вызова функции f у созданного объекта, значение стало 400. В Python использование global переменная и в функции класса, и в его конструкторе, и после описания класса дают возможность изменения глобальной переменной. Если убрать это объявление, то тогда выполнится присвоение локальной переменной.
Конечно же если мы определим локальную переменную в классе, то к ней не будет возможности доступа из другого класса:
class c1: x = 100 class c2: def f(self): print(x) o = c2() o.f() Traceback (most recent call last): File "main.py", line 7, in o.f() File "main.py", line 5, in f print(x) NameError: name 'x' is not defined
Для того, чтобы код работал, переменная x должна быль глобальной.
Заключение
Таким образом, область видимости переменных в языке программирования Python, является важной составляющей платформы. Правильное взаимодействие со всеми ее особенностями позволяет избежать множества довольно сложных ошибок. Для более безопасного контроля над видимостью отдельных объектов применяются ключевые слова global и nonlocal. Чтобы ознакомиться с дополнительными сведениями по данной теме, следует изучить PEP 3104.
