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

Есть ли перетеменные в Python?

1.3 Junior🔥 71 комментариев
#Python Core

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

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

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

Переменные в Python

Этот вопрос может означать несколько вещей. Я объясню разные интерпретации: 环境变量 (Environment Variables), глобальные переменные, локальные переменные и переменные потоков (Thread-local variables).

1. Environment Variables (переменные окружения)

Да, в Python есть доступ к переменным окружения системы:

import os

# Получить переменную окружения
database_url = os.environ.get('DATABASE_URL')
db_host = os.getenv('DB_HOST', 'localhost')  # С значением по умолчанию

# Установить переменную окружения
os.environ['MY_VAR'] = 'value'

# Все переменные окружения
all_env = os.environ

# Проверить наличие
if 'API_KEY' in os.environ:
    api_key = os.environ['API_KEY']

Лучшая практика — использовать python-dotenv:

from dotenv import load_dotenv
import os

# Загрузить из .env файла
load_dotenv()  # Ищет .env в текущей папке

api_key = os.getenv('API_KEY')
db_url = os.getenv('DATABASE_URL')

.env файл:

API_KEY=your_secret_key_here
DATABASE_URL=postgresql://user:password@localhost/dbname
DEBUG=True

2. Глобальные и локальные переменные

# Глобальная переменная
global_var = 10

def my_function():
    # Локальная переменная
    local_var = 20
    
    # Обращение к глобальной
    print(global_var)  # 10
    print(local_var)   # 20

my_function()

# Изменение глобальной переменной
global_counter = 0

def increment():
    global global_counter  # Объявляем, что используем глобальную
    global_counter += 1

increment()
print(global_counter)  # 1

3. Переменные потоков (Thread-local variables)

Это то же самое, что в других языках — переменные, уникальные для каждого потока:

import threading
import time

# Создаём thread-local хранилище
thread_local_data = threading.local()

def worker(thread_id):
    # Каждый поток имеет собственное значение
    thread_local_data.value = thread_id
    time.sleep(1)
    print(f"Thread {thread_id}: {thread_local_data.value}")

threads = []
for i in range(3):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

# Вывод:
# Thread 0: 0
# Thread 1: 1
# Thread 2: 2

Практический пример с базой данных:

import threading
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# Каждый поток получает свою сессию БД
db_thread_local = threading.local()

def get_db_session():
    if not hasattr(db_thread_local, 'session'):
        engine = create_engine('postgresql://...')
        Session = sessionmaker(bind=engine)
        db_thread_local.session = Session()
    return db_thread_local.session

def worker():
    session = get_db_session()  # Каждый поток получит свою
    # ... работа с БД ...
    session.close()

4. Класс с переменными экземпляра и класса

class MyClass:
    # Переменная класса (общая для всех экземпляров)
    class_var = 0
    
    def __init__(self, name):
        # Переменная экземпляра (уникальна для каждого объекта)
        self.instance_var = name
    
    @classmethod
    def increment_class_var(cls):
        cls.class_var += 1

obj1 = MyClass("Object 1")
obj2 = MyClass("Object 2")

print(obj1.instance_var)  # "Object 1"
print(obj2.instance_var)  # "Object 2"

# Но class_var общая
MyClass.increment_class_var()
print(MyClass.class_var)  # 1
print(obj1.class_var)     # 1
print(obj2.class_var)     # 1

5. Контекстные переменные (Context Variables)

Это современный способ для async приложений:

import asyncio
from contextvars import ContextVar

# Создаём контекстную переменную
user_id_var = ContextVar('user_id', default=None)

async def process_request(user_id):
    # Установить значение для текущего контекста
    token = user_id_var.set(user_id)
    
    # Все функции в этом контексте видят user_id
    print(f"Current user: {user_id_var.get()}")
    
    await some_async_function()
    
    # Восстановить предыдущее значение
    user_id_var.reset(token)

async def some_async_function():
    # Автоматически получит user_id из контекста
    print(f"In async func: {user_id_var.get()}")

async def main():
    await asyncio.gather(
        process_request(1),
        process_request(2),
        process_request(3)
    )

asyncio.run(main())

# Вывод:
# Current user: 1
# In async func: 1
# Current user: 2
# In async func: 2
# Current user: 3
# In async func: 3

Практический пример с Flask/FastAPI:

from contextvars import ContextVar
from fastapi import FastAPI, Request
from fastapi.middleware import Middleware

app = FastAPI()
request_id_var: ContextVar[str] = ContextVar('request_id', default=None)

@app.middleware("http")
async def add_request_id(request: Request, call_next):
    request_id = request.headers.get('x-request-id', 'unknown')
    token = request_id_var.set(request_id)
    
    try:
        response = await call_next(request)
    finally:
        request_id_var.reset(token)
    
    return response

@app.get("/data")
async def get_data():
    # Автоматически получит request_id
    logger.info(f"Processing request: {request_id_var.get()}")
    return {"status": "ok"}

6. Property (свойства класса)

Это похоже на переменные, но с вычислениями:

class Person:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
    
    @property
    def full_name(self):
        return f"{self.first_name} {self.last_name}"
    
    @full_name.setter
    def full_name(self, value):
        parts = value.split()
        self.first_name = parts[0]
        self.last_name = parts[1]

person = Person("John", "Doe")
print(person.full_name)  # "John Doe"
person.full_name = "Jane Smith"
print(person.first_name)  # "Jane"

7. Типизация переменных (Type Hints)

# Python 3.9+
from typing import Optional, Dict, List

# Простые типы
name: str = "John"
age: int = 30
height: float = 1.75
is_active: bool = True

# Сложные типы
users: List[str] = ["Alice", "Bob"]
scores: Dict[str, int] = {"Alice": 100, "Bob": 95}

# Опциональные значения
empty_value: Optional[str] = None
user_id: Optional[int] = 123

# Функции с типами
def greet(name: str, age: int) -> str:
    return f"Hello {name}, you are {age} years old"

result: str = greet("John", 30)

Итоговое сравнение типов переменных:

ТипОбласть видимостиПример
GlobalВсё приложениеglobal var = 10
LocalФункцияdef f(): x = 5
InstanceОбъектself.var = value
ClassКлассMyClass.var = value
Thread-localПотокthreading.local()
ContextAsync контекстContextVar('name')
EnvironmentOS переменныеos.environ['KEY']

Да, в Python есть все эти типы переменных, и они используются в зависимости от контекста и требований приложения.

Есть ли перетеменные в Python? | PrepBro