HTML Diff
1 added 1 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>13 ноя 2025</li>
2 <ul><li>13 ноя 2025</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><p>База, которую нужно знать для безопасной работы.</p>
4 </ul><p>База, которую нужно знать для безопасной работы.</p>
5 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
5 <p>Иллюстрация: Оля Ежак для Skillbox Media</p>
6 <p>Пишет о сетях, инструментах для разработчиков и языках программирования. Любит готовить, играть в инди‑игры и программировать на Python.</p>
6 <p>Пишет о сетях, инструментах для разработчиков и языках программирования. Любит готовить, играть в инди‑игры и программировать на Python.</p>
7 <p>Переменные в Python - одна из первых тем, с которой сталкиваются начинающие разработчики. На первый взгляд всё просто: создал переменную и работай. Но на практике оказывается, что они бывают разных видов. Особенно много проблем возникает с глобальными переменными, и именно они часто приводят к ошибкам.</p>
7 <p>Переменные в Python - одна из первых тем, с которой сталкиваются начинающие разработчики. На первый взгляд всё просто: создал переменную и работай. Но на практике оказывается, что они бывают разных видов. Особенно много проблем возникает с глобальными переменными, и именно они часто приводят к ошибкам.</p>
8 <p>В этой статье мы подробно разберём глобальные переменные. Вы узнаете, что это такое, почему их использование может приводить к непредсказуемому поведению программы и как с ними работать. Для лучшего понимания рекомендуем <a>выбрать редактор кода</a>, <a>установить Python на свой компьютер</a>и по ходу чтения запускать примеры кода.</p>
8 <p>В этой статье мы подробно разберём глобальные переменные. Вы узнаете, что это такое, почему их использование может приводить к непредсказуемому поведению программы и как с ними работать. Для лучшего понимания рекомендуем <a>выбрать редактор кода</a>, <a>установить Python на свой компьютер</a>и по ходу чтения запускать примеры кода.</p>
9 <p><strong>Содержание</strong></p>
9 <p><strong>Содержание</strong></p>
10 <ul><li><a>Что такое глобальные переменные и в чём их опасность</a></li>
10 <ul><li><a>Что такое глобальные переменные и в чём их опасность</a></li>
11 <li><a>Как глобальные переменные могут нарушать логику программы</a></li>
11 <li><a>Как глобальные переменные могут нарушать логику программы</a></li>
12 <li><a>Как работать с переменными в разных областях видимости</a></li>
12 <li><a>Как работать с переменными в разных областях видимости</a></li>
13 <li><a>Как управлять изменяемыми объектами и переприсваиванием</a></li>
13 <li><a>Как управлять изменяемыми объектами и переприсваиванием</a></li>
14 <li><a>Как организовать взаимодействие с глобальными переменными между модулями</a></li>
14 <li><a>Как организовать взаимодействие с глобальными переменными между модулями</a></li>
15 <li><a>Общие рекомендации по работе с глобальными переменными</a></li>
15 <li><a>Общие рекомендации по работе с глобальными переменными</a></li>
16 </ul><p>Глобальная переменная - это переменная, которая объявлена вне функции или класса. Её можно читать из любого места программы, но для изменения значения внутри функции нужно использовать специальное ключевое слово. Для начала давайте посмотрим пример.</p>
16 </ul><p>Глобальная переменная - это переменная, которая объявлена вне функции или класса. Её можно читать из любого места программы, но для изменения значения внутри функции нужно использовать специальное ключевое слово. Для начала давайте посмотрим пример.</p>
17 message = "Привет, мир!" def greet(): print(message) greet() # Привет, мир!<p>Переменная message объявлена глобально - вне функции. Поэтому функция greet() может прочитать её значение и вывести на экран.</p>
17 message = "Привет, мир!" def greet(): print(message) greet() # Привет, мир!<p>Переменная message объявлена глобально - вне функции. Поэтому функция greet() может прочитать её значение и вывести на экран.</p>
18 <p>Локальная переменная создаётся внутри функции и существует только в её области видимости. Она автоматически удаляется из памяти после завершения работы функции, освобождая ресурсы. Попробуйте сами:</p>
18 <p>Локальная переменная создаётся внутри функции и существует только в её области видимости. Она автоматически удаляется из памяти после завершения работы функции, освобождая ресурсы. Попробуйте сами:</p>
19 def greet(): message = "Привет, мир!" print("Внутри функции:", message) # Внутри функции: Привет, мир! greet() # После выполнения кода message больше не существует print("Снаружи функции:", message) # Ошибка: NameError: name 'message' is not defined<p>Ошибки возникают, когда локальная и глобальная переменные получают одинаковые имена. Python считает переменную внутри функции локальной, даже если вы пытаетесь прочитать её перед присваиванием. Вот пример кода, который выдаст UnboundLocalError.</p>
19 def greet(): message = "Привет, мир!" print("Внутри функции:", message) # Внутри функции: Привет, мир! greet() # После выполнения кода message больше не существует print("Снаружи функции:", message) # Ошибка: NameError: name 'message' is not defined<p>Ошибки возникают, когда локальная и глобальная переменные получают одинаковые имена. Python считает переменную внутри функции локальной, даже если вы пытаетесь прочитать её перед присваиванием. Вот пример кода, который выдаст UnboundLocalError.</p>
20 count = 10 # Глобальная переменная def show_count(): print(count) # Пытаемся вывести значение до присваивания count = 20 # После этой строки count становится локальной переменной show_count() # UnboundLocalError: cannot access local variable 'count' where it is not associated with a value<p>Интерпретатор Python анализирует весь код функции перед её выполнением. Когда он видит присваивание count = 20, то помечает count как локальную переменную на протяжении всей функции.</p>
20 count = 10 # Глобальная переменная def show_count(): print(count) # Пытаемся вывести значение до присваивания count = 20 # После этой строки count становится локальной переменной show_count() # UnboundLocalError: cannot access local variable 'count' where it is not associated with a value<p>Интерпретатор Python анализирует весь код функции перед её выполнением. Когда он видит присваивание count = 20, то помечает count как локальную переменную на протяжении всей функции.</p>
21 <p>Поэтому при попытке вывести print(count) перед присваиванием Python обращается к локальной переменной count, которая ещё не инициализирована. В результате возникает ошибка UnboundLocalError.</p>
21 <p>Поэтому при попытке вывести print(count) перед присваиванием Python обращается к локальной переменной count, которая ещё не инициализирована. В результате возникает ошибка UnboundLocalError.</p>
22 <p>Помимо технических ошибок, глобальные переменные создают скрытые зависимости между частями программы. В результате любая функция может неожиданно изменить значение переменной, что повлияет на поведение других функций и модулей. Например, может измениться выполнение условий в конструкциях if, результаты вычислений или последовательность операций в других частях кода.</p>
22 <p>Помимо технических ошибок, глобальные переменные создают скрытые зависимости между частями программы. В результате любая функция может неожиданно изменить значение переменной, что повлияет на поведение других функций и модулей. Например, может измениться выполнение условий в конструкциях if, результаты вычислений или последовательность операций в других частях кода.</p>
23 <p>Проблема зависимостей особенно заметна в крупных проектах с десятками функций и модулей, где одну переменную читают и изменяют из разных мест. Разработчику приходится держать в уме все возможные точки изменения, чтобы понять состояние программы.</p>
23 <p>Проблема зависимостей особенно заметна в крупных проектах с десятками функций и модулей, где одну переменную читают и изменяют из разных мест. Разработчику приходится держать в уме все возможные точки изменения, чтобы понять состояние программы.</p>
24 <p>Например, в коде ниже обе функции используют глобальную переменную processing_mode. Функция main() задаёт ей значение 1 и ожидает стандартного режима работы программы. Однако вызов process_data() меняет это значение на 2. В итоге условие в main() выполняется неверно, поскольку состояние программы стало другим.</p>
24 <p>Например, в коде ниже обе функции используют глобальную переменную processing_mode. Функция main() задаёт ей значение 1 и ожидает стандартного режима работы программы. Однако вызов process_data() меняет это значение на 2. В итоге условие в main() выполняется неверно, поскольку состояние программы стало другим.</p>
25 # Глобальная настройка режима обработки processing_mode = 0 # 0 - не установлен, 1 - стандарт, 2 - спецрежим def process_data(): global processing_mode processing_mode = 2 # Меняем режим print("Данные обработаны") def main(): global processing_mode processing_mode = 1 # Ожидаем стандартный режим для остального кода process_data() # Во время вызова режим станет 2 # Логика опирается на состояние, которое мы изменили if processing_mode == 1: print("Стандартная обработка") else: print("Режим изменён unexpectedly") main() # Режим изменён unexpectedly<p>Проблема скрытых зависимостей возникает именно с изменяемыми глобальными переменными - теми, которые программа модифицирует во время работы. Это могут быть счётчики вызовов функций, флаги состояния системы или накопители промежуточных результатов.</p>
25 # Глобальная настройка режима обработки processing_mode = 0 # 0 - не установлен, 1 - стандарт, 2 - спецрежим def process_data(): global processing_mode processing_mode = 2 # Меняем режим print("Данные обработаны") def main(): global processing_mode processing_mode = 1 # Ожидаем стандартный режим для остального кода process_data() # Во время вызова режим станет 2 # Логика опирается на состояние, которое мы изменили if processing_mode == 1: print("Стандартная обработка") else: print("Режим изменён unexpectedly") main() # Режим изменён unexpectedly<p>Проблема скрытых зависимостей возникает именно с изменяемыми глобальными переменными - теми, которые программа модифицирует во время работы. Это могут быть счётчики вызовов функций, флаги состояния системы или накопители промежуточных результатов.</p>
26 <p>Однако при работе с константами проблемы со скрытыми зависимостями нет. Например, константы вроде MAX_CONNECTIONS = 100 (максимальное количество подключений к серверу) или API_URL = "&lt;<a>https://api.example.com</a>&gt;" (адрес внешнего API) задаются один раз при запуске программы и не меняются в процессе её работы. Их принято записывать заглавными буквами и выносить в отдельный модуль.</p>
26 <p>Однако при работе с константами проблемы со скрытыми зависимостями нет. Например, константы вроде MAX_CONNECTIONS = 100 (максимальное количество подключений к серверу) или API_URL = "&lt;<a>https://api.example.com</a>&gt;" (адрес внешнего API) задаются один раз при запуске программы и не меняются в процессе её работы. Их принято записывать заглавными буквами и выносить в отдельный модуль.</p>
27 <p>Чтобы избежать конфликтов имён, необходимо понимать области видимости переменных - правила, определяющие, где переменная доступна для чтения и изменения. Главный принцип: переменная доступна там, где она создана, и во всех вложенных блоках кода.</p>
27 <p>Чтобы избежать конфликтов имён, необходимо понимать области видимости переменных - правила, определяющие, где переменная доступна для чтения и изменения. Главный принцип: переменная доступна там, где она создана, и во всех вложенных блоках кода.</p>
28 <p>Вернёмся к примеру с ошибкой UnboundLocalError и исправим её. Чтобы изменить глобальную переменную внутри функции, нужно использовать перед её именем ключевое слово global. Это явно указывает Python, что мы работаем с глобальной переменной, а не создаём новую локальную. Давайте посмотрим на примере.</p>
28 <p>Вернёмся к примеру с ошибкой UnboundLocalError и исправим её. Чтобы изменить глобальную переменную внутри функции, нужно использовать перед её именем ключевое слово global. Это явно указывает Python, что мы работаем с глобальной переменной, а не создаём новую локальную. Давайте посмотрим на примере.</p>
29 count = 10 def show_count(): global count # Указываем, что хотим изменить глобальную переменную count = 20 # Меняем глобальную переменную print("Внутри функции:", count) show_count() # Внутри функции: 20 print("Снаружи функции:", count) # Снаружи функции: 20<p>Оператор global в Python - не единственный способ управления областью видимости переменных. Для работы с переменными из внешней (но не глобальной) области видимости во вложенных функциях используется ключевое слово nonlocal. Оно позволяет изменять переменные, определённые в объемлющей функции. Синтаксис такой же, как у global: nonlocal имя_переменной.</p>
29 count = 10 def show_count(): global count # Указываем, что хотим изменить глобальную переменную count = 20 # Меняем глобальную переменную print("Внутри функции:", count) show_count() # Внутри функции: 20 print("Снаружи функции:", count) # Снаружи функции: 20<p>Оператор global в Python - не единственный способ управления областью видимости переменных. Для работы с переменными из внешней (но не глобальной) области видимости во вложенных функциях используется ключевое слово nonlocal. Оно позволяет изменять переменные, определённые в объемлющей функции. Синтаксис такой же, как у global: nonlocal имя_переменной.</p>
30 count = 100 def outer(): count = 10 # Переменная внешней функции def inner(): nonlocal count # Меняем переменную из outer() count += 5 print("Внутри inner:", count) # Внутри inner: 15 inner() print("После inner в outer:", count) # После inner в outer: 15 outer() print("Снаружи функции:", count) # Снаружи функции: 100<p>Когда Python встречает переменную, он ищет её по строгому алгоритму -<a>правилу LEGB</a>. Это обозначение уровней областей видимости:</p>
30 count = 100 def outer(): count = 10 # Переменная внешней функции def inner(): nonlocal count # Меняем переменную из outer() count += 5 print("Внутри inner:", count) # Внутри inner: 15 inner() print("После inner в outer:", count) # После inner в outer: 15 outer() print("Снаружи функции:", count) # Снаружи функции: 100<p>Когда Python встречает переменную, он ищет её по строгому алгоритму -<a>правилу LEGB</a>. Это обозначение уровней областей видимости:</p>
31 <ul><li><strong>Local</strong> - локальная область внутри функции.</li>
31 <ul><li><strong>Local</strong> - локальная область внутри функции.</li>
32 <li><strong>Enclosing</strong> - область внешней функции (для вложенных функций).</li>
32 <li><strong>Enclosing</strong> - область внешней функции (для вложенных функций).</li>
33 <li><strong>Global</strong> - глобальная область видимости модуля.</li>
33 <li><strong>Global</strong> - глобальная область видимости модуля.</li>
34 <li><strong>Built-in</strong> - встроенная область Python с предопределёнными функциями и исключениями (len(), print(), str() и другие).</li>
34 <li><strong>Built-in</strong> - встроенная область Python с предопределёнными функциями и исключениями (len(), print(), str() и другие).</li>
35 </ul><p>Python проверяет эти области последовательно: сначала локальную, затем внешнюю, потом глобальную и, наконец, встроенную.</p>
35 </ul><p>Python проверяет эти области последовательно: сначала локальную, затем внешнюю, потом глобальную и, наконец, встроенную.</p>
36 Области видимости переменных в Python: интерпретатор начинает поиск из центра и движется к внешним кругам, пока не найдёт нужное имя<em>Инфографика: Майя Мальгина для Skillbox Media</em><p>Если вы работаете с изменяемыми объектами вроде списков, словарей или множеств - их содержимое можно менять без ключевого слова global. Это работает потому, что мы не переприсваиваем саму переменную, а модифицируем содержимое объекта, на который она ссылается. Python позволяет вызывать методы и изменять элементы таких объектов без явного объявления переменной как глобальной.</p>
36 Области видимости переменных в Python: интерпретатор начинает поиск из центра и движется к внешним кругам, пока не найдёт нужное имя<em>Инфографика: Майя Мальгина для Skillbox Media</em><p>Если вы работаете с изменяемыми объектами вроде списков, словарей или множеств - их содержимое можно менять без ключевого слова global. Это работает потому, что мы не переприсваиваем саму переменную, а модифицируем содержимое объекта, на который она ссылается. Python позволяет вызывать методы и изменять элементы таких объектов без явного объявления переменной как глобальной.</p>
37 config = {"debug": False} # Глобальный словарь def enable_debug(): # global не нужен для изменения содержимого config["debug"] = True config["mode"] = "verbose" print("Debug включён") enable_debug() print(config) # {'debug': True, 'mode': 'verbose'}<p>Но если бы мы попытались присвоить переменной config новый словарь, здесь уже понадобилось бы ключевое слово global.</p>
37 config = {"debug": False} # Глобальный словарь def enable_debug(): # global не нужен для изменения содержимого config["debug"] = True config["mode"] = "verbose" print("Debug включён") enable_debug() print(config) # {'debug': True, 'mode': 'verbose'}<p>Но если бы мы попытались присвоить переменной config новый словарь, здесь уже понадобилось бы ключевое слово global.</p>
38 config = {"debug": False} def reset_config(): global config # Теперь global нужен config = {} # Полное переприсваивание print("Конфиг сброшен") reset_config() print(config) # {}<p>В реальных проектах код разбивается на модули, поэтому часто необходимо использовать одну глобальную переменную в разных файлах. Самый простой способ - создать отдельный модуль для хранения глобальных переменных. Назовём его settings.py.</p>
38 config = {"debug": False} def reset_config(): global config # Теперь global нужен config = {} # Полное переприсваивание print("Конфиг сброшен") reset_config() print(config) # {}<p>В реальных проектах код разбивается на модули, поэтому часто необходимо использовать одну глобальную переменную в разных файлах. Самый простой способ - создать отдельный модуль для хранения глобальных переменных. Назовём его settings.py.</p>
39 # settings.py APP_NAME = "MyApp" DEBUG_MODE = False max_connections = 100<p>Теперь эти переменные можно импортировать в другие модули с помощью оператора import и обращаться к ним через имя модуля.</p>
39 # settings.py APP_NAME = "MyApp" DEBUG_MODE = False max_connections = 100<p>Теперь эти переменные можно импортировать в другие модули с помощью оператора import и обращаться к ним через имя модуля.</p>
40 # main.py import settings print(settings.APP_NAME) # MyApp print(settings.max_connections) # 100<p>Чтобы изменить глобальную переменную из другого модуля, обращайтесь к ней через имя модуля.</p>
40 # main.py import settings print(settings.APP_NAME) # MyApp print(settings.max_connections) # 100<p>Чтобы изменить глобальную переменную из другого модуля, обращайтесь к ней через имя модуля.</p>
41 # main.py import settings def toggle_debug(): settings.DEBUG_MODE = not settings.DEBUG_MODE print(f"Debug mode: {settings.DEBUG_MODE}") toggle_debug() # Debug mode: True<p>Если вы импортируете переменную напрямую через конструкцию from settings import DEBUG_MODE, то получите копию её значения, а не ссылку на переменную в модуле settings. Это значит, что любые изменения этой переменной в текущем модуле создадут локальную переменную и не повлияют на исходное значение в settings.py.</p>
41 # main.py import settings def toggle_debug(): settings.DEBUG_MODE = not settings.DEBUG_MODE print(f"Debug mode: {settings.DEBUG_MODE}") toggle_debug() # Debug mode: True<p>Если вы импортируете переменную напрямую через конструкцию from settings import DEBUG_MODE, то получите копию её значения, а не ссылку на переменную в модуле settings. Это значит, что любые изменения этой переменной в текущем модуле создадут локальную переменную и не повлияют на исходное значение в settings.py.</p>
42 # Неправильный способ для изменяемых значений from settings import DEBUG_MODE # Импортируется копия значения, а не сама переменная DEBUG_MODE = True # Создаёт новую локальную переменную, не изменяя settings.DEBUG_MODE<p>Исключение касается изменяемых объектов - для них можно использовать прямой импорт, поскольку мы модифицируем содержимое объекта, а не переприсваиваем саму переменную.</p>
42 # Неправильный способ для изменяемых значений from settings import DEBUG_MODE # Импортируется копия значения, а не сама переменная DEBUG_MODE = True # Создаёт новую локальную переменную, не изменяя settings.DEBUG_MODE<p>Исключение касается изменяемых объектов - для них можно использовать прямой импорт, поскольку мы модифицируем содержимое объекта, а не переприсваиваем саму переменную.</p>
43 # settings.py users = ["admin", "guest"] # Глобальный список пользователей # main.py from settings import users # Импортируем объект списка users.append("editor") # Добавляем элемент, не переприсваивая переменную print(users) # ['admin', 'guest', 'editor']<p>В примере выше глобальная переменная users определена как список - изменяемый объект. При импорте через from settings import users Python передаёт только ссылку на объект, а не копию данных. Поэтому users.append ("editor") изменяет содержимое списка в модуле settings, но не создаёт при этом новую переменную. Однако если бы произошло переприсваивание (например, users = ["editor"]), то Python создал бы новую локальную переменную, не затронув исходный список.</p>
43 # settings.py users = ["admin", "guest"] # Глобальный список пользователей # main.py from settings import users # Импортируем объект списка users.append("editor") # Добавляем элемент, не переприсваивая переменную print(users) # ['admin', 'guest', 'editor']<p>В примере выше глобальная переменная users определена как список - изменяемый объект. При импорте через from settings import users Python передаёт только ссылку на объект, а не копию данных. Поэтому users.append ("editor") изменяет содержимое списка в модуле settings, но не создаёт при этом новую переменную. Однако если бы произошло переприсваивание (например, users = ["editor"]), то Python создал бы новую локальную переменную, не затронув исходный список.</p>
44 <p>Ещё один подход - использовать функции для доступа к глобальным переменным. Такие переменные часто называют "приватными" и обозначают подчёркиванием в начале имени - например, _debug_mode.</p>
44 <p>Ещё один подход - использовать функции для доступа к глобальным переменным. Такие переменные часто называют "приватными" и обозначают подчёркиванием в начале имени - например, _debug_mode.</p>
45 <p>Это не делает переменную закрытой, поскольку Python не запрещает к ней доступ. Но такое имя служит предупреждением для разработчиков: переменную не следует изменять напрямую - только через функции.</p>
45 <p>Это не делает переменную закрытой, поскольку Python не запрещает к ней доступ. Но такое имя служит предупреждением для разработчиков: переменную не следует изменять напрямую - только через функции.</p>
46 # settings.py _debug_mode = False # Внутренняя переменная def is_debug(): # Возвращает текущее значение глобальной переменной return _debug_mode def set_debug(value): # Меняет значение глобальной переменной global _debug_mode _debug_mode = value # main.py import settings # Модуль с настройками settings.set_debug(True) # Меняем значение через функцию print(settings.is_debug()) # Проверяем состояние: True<p>Переменная _debug_mode хранится в модуле settings.py, а функции is_debug() и set_debug() обеспечивают к ней контролируемый доступ. Этот подход защищает глобальные данные от случайных изменений и упрощает отладку: вся логика обновления проходит через одну точку.</p>
46 # settings.py _debug_mode = False # Внутренняя переменная def is_debug(): # Возвращает текущее значение глобальной переменной return _debug_mode def set_debug(value): # Меняет значение глобальной переменной global _debug_mode _debug_mode = value # main.py import settings # Модуль с настройками settings.set_debug(True) # Меняем значение через функцию print(settings.is_debug()) # Проверяем состояние: True<p>Переменная _debug_mode хранится в модуле settings.py, а функции is_debug() и set_debug() обеспечивают к ней контролируемый доступ. Этот подход защищает глобальные данные от случайных изменений и упрощает отладку: вся логика обновления проходит через одну точку.</p>
47 <p>Например, чтобы добавить логирование или проверку при изменении _debug_mode, нужно поправить функцию set_debug() - не придётся искать все места, где переменная могла быть изменена напрямую.</p>
47 <p>Например, чтобы добавить логирование или проверку при изменении _debug_mode, нужно поправить функцию set_debug() - не придётся искать все места, где переменная могла быть изменена напрямую.</p>
48 <p>Хотя глобальные переменные могут создавать проблемы, иногда без них не обойтись. Например, они полезны для хранения настроек или общих ресурсов. Если вам всё же нужно их использовать, соблюдайте несколько правил - они помогут избежать распространённых ошибок.</p>
48 <p>Хотя глобальные переменные могут создавать проблемы, иногда без них не обойтись. Например, они полезны для хранения настроек или общих ресурсов. Если вам всё же нужно их использовать, соблюдайте несколько правил - они помогут избежать распространённых ошибок.</p>
49 <p><strong>Добавляйте префикс</strong><strong>g_</strong><strong>к именам глобальных переменных.</strong>По префиксу каждый разработчик может понять, что переменная относится к глобальной области и с ней нужно быть осторожней.</p>
49 <p><strong>Добавляйте префикс</strong><strong>g_</strong><strong>к именам глобальных переменных.</strong>По префиксу каждый разработчик может понять, что переменная относится к глобальной области и с ней нужно быть осторожней.</p>
50 g_counter = 0 g_user_session = None def increment(): global g_counter g_counter += 1 print(f"Счётчик: {g_counter}") increment() # Счётчик: 1<p><strong>Передавайте глобальные переменные как параметры функций.</strong>Вместо прямого обращения к глобальным переменным передавайте их значения через аргументы. Это делает зависимости явными, упрощает тестирование и повышает переиспользуемость кода.</p>
50 g_counter = 0 g_user_session = None def increment(): global g_counter g_counter += 1 print(f"Счётчик: {g_counter}") increment() # Счётчик: 1<p><strong>Передавайте глобальные переменные как параметры функций.</strong>Вместо прямого обращения к глобальным переменным передавайте их значения через аргументы. Это делает зависимости явными, упрощает тестирование и повышает переиспользуемость кода.</p>
51 # Было: функция обращается к глобальной переменной напрямую g_config = {"debug": True, "verbose": False} def process_data(): if g_config["debug"]: # Зависимость от внешней переменной print("Debug mode") return "data" # Стало: конфигурация передаётся явно через параметр def process_data(config): # Теперь видно, от каких данных зависит функция if config["debug"]: print("Debug mode") return "data" # Передаём конфигурацию при вызове и можем тестировать функцию с разными параметрами result = process_data(g_config)<p><strong>Используйте как можно меньше изменяемых глобальных переменных.</strong>Старайтесь применять глобальные переменные для констант, параметров конфигурации, единственного экземпляра объекта, счётчиков и флагов - когда другие решения избыточны.</p>
51 # Было: функция обращается к глобальной переменной напрямую g_config = {"debug": True, "verbose": False} def process_data(): if g_config["debug"]: # Зависимость от внешней переменной print("Debug mode") return "data" # Стало: конфигурация передаётся явно через параметр def process_data(config): # Теперь видно, от каких данных зависит функция if config["debug"]: print("Debug mode") return "data" # Передаём конфигурацию при вызове и можем тестировать функцию с разными параметрами result = process_data(g_config)<p><strong>Используйте как можно меньше изменяемых глобальных переменных.</strong>Старайтесь применять глобальные переменные для констант, параметров конфигурации, единственного экземпляра объекта, счётчиков и флагов - когда другие решения избыточны.</p>
52 <p>Для остального рассмотрите альтернативные подходы: передавайте параметры через функции, применяйте классы или контекстные менеджеры. Например, вместо глобального счётчика запросов, который может изменяться из разных частей программы, используйте класс.</p>
52 <p>Для остального рассмотрите альтернативные подходы: передавайте параметры через функции, применяйте классы или контекстные менеджеры. Например, вместо глобального счётчика запросов, который может изменяться из разных частей программы, используйте класс.</p>
53 - # Плохо: глобальная изменяемая переменная request_count = 0 def handle_request(): global request_count request_count += 1 print(f"Запросов: {request_count}") # Хорошо: инкапсуляция состояния в класс class RequestCounter: def __init__(self): self.count = 0 def increment(self): self.count += 1 print(f"Запросов: {self.count}") counter = RequestCounter() counter.increment() # Запросов: 1<p>Вместо глобальной переменной мы создаём класс RequestCounter, который инкапсулирует состояние счётчика и обеспечивает контролируемый доступ через метод increment(). Это позволяет каждой части программы работать со своим счётчиком - данные изолированы, и разные модули не могут непредсказуемо изменять общее состояние.</p>
53 + # Плохо: глобальная изменяемая переменная request_count = 0 def handle_request(): global request_count request_count += 1 print(f"Запросов: {request_count}") # Хорошо: инкапсуляция состояния в класс class RequestCounter: def __init__(self): self.count = 0 def increment(self): self.count += 1 print(f"Запросов: {self.count}") counter = RequestCounter() counter.increment() # Запросов: 1<p>Вместо глобальной переменной мы создаём класс RequestCounter, который инкапсулирует состояние счётчика и обеспечивает контролруемый доступ через метод increment(). Это позволяет каждой части программы работать со своим счётчиком - данные изолированы, и разные модули не могут непредсказуемо изменять общее состояние.</p>
54 <p>Кроме того, такой подход упрощает тестирование. Вы можете создать новый экземпляр RequestCounter для каждого теста и не беспокоиться о побочных эффектах от других частей кода. А если потребуется добавить логирование или валидацию при увеличении счётчика, достаточно изменить метод increment() - вся логика будет собрана в одном месте.</p>
54 <p>Кроме того, такой подход упрощает тестирование. Вы можете создать новый экземпляр RequestCounter для каждого теста и не беспокоиться о побочных эффектах от других частей кода. А если потребуется добавить логирование или валидацию при увеличении счётчика, достаточно изменить метод increment() - вся логика будет собрана в одном месте.</p>
55 <p>Python для всех</p>
55 <p>Python для всех</p>
56 <p>Вы освоите Python на практике и создадите проекты для портфолио - телеграм-бот, веб-парсер и сайт с нуля. А ещё получите готовый план выхода на удалёнку и фриланс. Спикер - руководитель отдела разработки в "Сбере".</p>
56 <p>Вы освоите Python на практике и создадите проекты для портфолио - телеграм-бот, веб-парсер и сайт с нуля. А ещё получите готовый план выхода на удалёнку и фриланс. Спикер - руководитель отдела разработки в "Сбере".</p>
57 <p><a>Пройти бесплатно</a></p>
57 <p><a>Пройти бесплатно</a></p>
58 <a><b>Бесплатный курс по разработке на Python ➞</b>Пройдите бесплатный курс по Python и создайте с нуля телеграм-бот, веб-парсер и сайт. Спикер - руководитель отдела разработки в "Сбере". Пройти курс</a>
58 <a><b>Бесплатный курс по разработке на Python ➞</b>Пройдите бесплатный курс по Python и создайте с нуля телеграм-бот, веб-парсер и сайт. Спикер - руководитель отдела разработки в "Сбере". Пройти курс</a>