Как сделать переменную глобальной python
Перейти к содержимому

Как сделать переменную глобальной python

  • автор:

Локальные и глобальные переменные в 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 можно сделать следующие обобщающие выводы:

  1. Использование значений глобальных переменных допускается в любом месте модуля (файла с программой), как внутри программных блоков (функций, классов, методов или процедур), так и вне их.
  2. Значения локальных переменных внутри тех программных блоков, где они были объявлены могут без ограничений, как использоваться, так и изменяться.
  3. В случае наличия в модули одноименных глобальных и локальных переменных, внутри программных блоков могут быть доступны лишь значения объявленных там локальных переменных. Этот процесс называется затенением переменных.
  4. Внутри программных блоков каждая переменная должна однозначно восприниматься интерпретатором, либо как локальная, либо как глобальная. Двух одноименных переменных с разными областями видимости в интерпретаторе быть не может.
  5. Оператор присвоения внутри программных блоков в случае одноименных глобальных и локальных переменных всегда глобальную переменную замещает локальной, что может привести к ошибки при использовании данной переменной до ее инициализации.

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

В программировании особое внимание уделяется концепции о локальных и глобальных переменных, а также связанное с ними представление об областях видимости. Соответственно, локальные переменные видны только в локальной области видимости, которой может выступать отдельно взятая функция. Глобальные переменные видны во всей программе. «Видны» – значит, известны, доступны. К ним можно обратиться по имени и получить связанное с ними значение.

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

Вернемся к нашей программе из прошлого урока, немного упростив ее для удобства:

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. Введение в программирование

Руководство по глобальным переменным

Переменная, доступ к которой можно получить из любого места в коде, называется глобальной. Ее можно определить вне блока. Другими словами, глобальная переменная, объявленная вне функции, будет доступна внутри нее.

С другой стороны, переменная, объявленная внутри определенного блока кода, будет видна только внутри этого же блока — она называется локальной.

Разберемся с этими понятиями на примере.

Пример локальных и глобальных переменных

 
 
def sum(): a = 10 # локальные переменные b = 20 c = a + b print("Сумма:", c) sum()

Переменная объявлена внутри функции и может использоваться только в ней. Получить доступ к этой локальной функции в других нельзя.

Для решения этой проблемы используются глобальные переменные.

Теперь взгляните на этот пример с глобальными переменными:

 
 
a = 20 # определены вне функции b = 10 def sum(): c = a + b # Использование глобальных переменных print("Сумма:", c) def sub(): d = a - b # Использование глобальных переменных print("Разница:", d) sum() sub()
Сумма: 30 Разница: 10

В этом коде были объявлены две глобальные переменные: a и b . Они используются внутри функций sum() и sub() . Обе возвращают результат при вызове.

Если определить локальную переменную с тем же именем, то приоритет будет у нее. Посмотрите, как в функции msg это реализовано.

 
 
def msg(): m = "Привет, как дела?" print(m) msg() m = "Отлично!" # глобальная переменная print(m)
Привет, как дела? Отлично!

Здесь была объявлена локальная переменная с таким же именем, как и у глобальной. Сперва выводится значение локальной, а после этого — глобальной.

Ключевое слово global

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

Правила использования global

  • Если значение определено на выходе функции, то оно автоматически станет глобальной переменной.
  • Ключевое слово global используется для объявления глобальной переменной внутри функции.
  • Нет необходимости использовать global для объявления глобальной переменной вне функции.
  • Переменные, на которые есть ссылка внутри функции, неявно являются глобальными.

Пример без использования глобального ключевого слова.

 
 
c = 10 def mul(): c = c * 10 print(c) mul()
line 5, in mul c = c * 10 UnboundLocalError: local variable 'c' referenced before assignment

Этот код вернул ошибку, потому что была предпринята попытка присвоить значение глобальной переменной. Изменять значение можно только с помощью ключевого слова global .

 
c = 10 def mul(): global c c = c * 10 print("Значение в функции:", c) mul() print("Значение вне функции:", c)
Значение в функции: 100 Значение вне функции: 100

Здесь переменная c была объявлена в функции mul() с помощью ключевого слова global . Ее значение умножается на 10 и становится равным 100. В процессе работы программы можно увидеть, что изменение значения внутри функции отражается на глобальном значении переменной.

Глобальные переменные в модулях Python

Преимущество использования ключевого слова global — в возможности создавать глобальные переменные и передавать их между модулями. Например, можно создать name.py, который бы состоял из глобальных переменных. Если их изменить, то изменения повлияют на все места, где эти переменные встречаются.

1. Создаем файл name.py для хранения глобальных переменных:

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 видео

ВЫБОР ЦВЕТА

colorpicker

курс сегодня!

Сообщить об ошибке

Если вы хотите сообщить об ошибке или внести предложение, не стесняйтесь отправлять на электронное письмо:

Ваше предложение:

Спасибо Вам за то, что помогаете!

Ваше сообщение было отправлено в SchoolsW3.

ТОП Учебники
ТОП Справочники
ТОП Примеры
Получить сертификат

SchoolsW3 оптимизирован для бесплатного обучения, проверки и подготовки знаний. Примеры в редакторе упрощают и улучшают чтение и базовое понимание. Учебники, ссылки, примеры постоянно пересматриваются, чтобы избежать ошибок, но не возможно гарантировать полную правильность всего содержания. Некоторые страницы сайта могут быть не переведены на РУССКИЙ язык, можно отправить страницу как ошибку, так же можете самостоятельно заняться переводом. Используя данный сайт, вы соглашаетесь прочитать и принять Условия к использованию, Cookies и политика конфиденциальности.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *