← Назад к вопросам

Как сделать переменную из функции глобальной?

1.0 Junior🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как сделать переменную из функции глобальной в Python

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

1. Базовое использование global

counter = 0

def increment():
    global counter  # Указываем, что используем глобальную переменную
    counter += 1
    return counter

print(counter)          # 0
print(increment())      # 1
print(counter)          # 1 (изменилась глобальная переменная)
print(increment())      # 2
print(counter)          # 2

2. Создание новой глобальной переменной

def create_global():
    global message
    message = "Hello, World!"  # Создаём глобальную переменную

print(message)  # NameError! Переменной ещё нет

create_global()
print(message)  # Hello, World!

3. Частые ошибки

Ошибка 1: Забыли global

x = 10

def modify_x():
    x = 20  # Это создаёт ЛОКАЛЬНУЮ переменную x
    print(x)  # 20

modify_x()
print(x)  # 10 (глобальная переменная не изменилась!)

# ✅ Правильно
def modify_x():
    global x
    x = 20

modify_x()
print(x)  # 20

Ошибка 2: global в неправильном месте

# ❌ ПЛОХО: global после использования переменной
def bad_function():
    print(x)  # UnboundLocalError!
    global x
    x = 10

# ✅ ХОРОШО: global в начале функции
def good_function():
    global x
    print(x)
    x = 10

4. Работа с глобальными структурами данных

Для изменения содержимого (не переназначения) не нужно global:

global_list = [1, 2, 3]
global_dict = {"key": "value"}

def modify_list():
    # НЕ нужно global, если только изменяем содержимое
    global_list.append(4)  # Работает
    global_list[0] = 99    # Работает

modify_list()
print(global_list)  # [99, 2, 3, 4]

# ❌ НЕ работает без global (переназначение)
def replace_list():
    global_list = [5, 6, 7]  # Создаёт локальную переменную

# ✅ Работает с global
def replace_list_correctly():
    global global_list
    global_list = [5, 6, 7]  # Переназначает глобальную

5. Global переменные в классах

global_counter = 0

class Counter:
    def increment(self):
        global global_counter  # Можно использовать в методах
        global_counter += 1
        return global_counter

counter = Counter()
print(counter.increment())  # 1
print(global_counter)       # 1

# ⚠️ Это плохая практика! Используйте атрибуты класса вместо этого
# ✅ Лучше так:
class BetterCounter:
    count = 0  # Атрибут класса
    
    def increment(self):
        BetterCounter.count += 1
        return BetterCounter.count

better = BetterCounter()
print(better.increment())  # 1
print(BetterCounter.count)  # 1

6. Глобальные переменные и области видимости

x = "глобальная"

def outer():
    x = "из outer"
    
    def inner():
        # nonlocal используется для доступа к переменной из enclosing scope
        nonlocal x
        x = "из inner"
    
    inner()
    print(x)  # из inner

outer()
print(x)  # глобальная (не изменилась)

# Для глобальной переменной
y = "глобальная"

def func():
    global y
    y = "изменена"

func()
print(y)  # изменена

7. nonlocal vs global

def outer():
    x = 10  # Переменная в enclosing scope
    
    def middle():
        y = 20  # Переменная в middle scope
        
        def inner():
            nonlocal y  # Доступ к y из middle
            global x    # ❌ ОШИБКА: x находится в outer, не глобальный
            y = 30
        
        inner()
        print(y)  # 30
    
    middle()

outer()

# Правильно:
x = "глобальная"

def outer():
    y = 10
    
    def inner():
        global x
        nonlocal y
        x = "изменена"
        y = 20
    
    inner()
    print(y)  # 20

outer()
print(x)  # изменена

8. globals() функция

# Получить словарь всех глобальных переменных
my_global = 42

print(globals()["my_global"])  # 42

# Можно изменять через globals()
globals()["new_var"] = "создана через globals()"
print(new_var)  # создана через globals()

# Получить значение динамически
var_name = "my_global"
print(globals().get(var_name))  # 42

# Проверить наличие
if "my_global" in globals():
    print("my_global существует")

9. Практический пример: Конфигурация приложения

# ❌ ПЛОХО: использование global для конфигурации
config = {}

def load_config(env: str):
    global config
    if env == "dev":
        config = {"debug": True, "db": "localhost"}
    else:
        config = {"debug": False, "db": "prod-server"}

load_config("dev")
print(config["debug"])  # True

# ✅ ХОРОШО: использование класса
class Config:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def load(self, env: str):
        if env == "dev":
            self.debug = True
            self.db = "localhost"
        else:
            self.debug = False
            self.db = "prod-server"

config = Config()
config.load("dev")
print(config.debug)  # True

# Ещё лучше: использование файла конфигурации
import os

class AppConfig:
    DEBUG = os.getenv("DEBUG", "False") == "True"
    DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///db.sqlite3")
    SECRET_KEY = os.getenv("SECRET_KEY", "dev-key")

print(AppConfig.DEBUG)
print(AppConfig.DATABASE_URL)

10. Когда использовать глобальные переменные

Используй global для:

  • Конфигурационных значений (но лучше через класс)
  • Кэшей (но лучше через функции с состоянием)
  • Регистров/флагов (но лучше через контекст)

НЕ используй global для:

  • Состояния приложения (используй классы)
  • Данных, которые должны изменяться (используй параметры)
  • Множественных переменных (используй словарь или класс)

Вывод

Правило: Избегай глобальных переменных

Глобальные переменные могут привести к:

  • Сложности отладки
  • Побочным эффектам
  • Непредсказуемому поведению
  • Сложности тестирования

Используйте вместо этого:

  1. Параметры функций — явный ввод
  2. Возвращаемые значения — явный вывод
  3. Классы — инкапсуляция состояния
  4. Контекстные переменные — для потокобезопасности
  5. Dependency Injection — передача зависимостей

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