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

Как обращаться к переменным?

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

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

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

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

Способы обращения к переменным в Python

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

Локальные переменные — это переменные, объявленные внутри функции или блока кода. Они существуют только в области видимости этой функции.

def process_data():
    data = [1, 2, 3]  # Локальная переменная
    result = sum(data)  # Локальная переменная
    return result

value = process_data()
print(value)  # Работает
print(data)  # NameError: data не определена

Глобальные переменные

Глобальные переменные определяются на уровне модуля и доступны везде.

# Глобальная переменная
DATABASE_HOST = "localhost"
DATABASE_PORT = 5432

def connect_to_db():
    # Читаем глобальную переменную
    print(f"Подключение к {DATABASE_HOST}:{DATABASE_PORT}")

connect_to_db()

Если нужно изменить глобальную переменную:

counter = 0

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

increment()
increment()
print(counter)  # 2

Переменные экземпляра (Instance Variables)

self. — обращение к переменным экземпляра класса:

class DataProcessor:
    def __init__(self, name):
        self.name = name  # Переменная экземпляра
        self.data = None
    
    def load_data(self):
        self.data = [1, 2, 3]  # Присваиваем значение
        print(f"Процессор {self.name} загрузил данные")
    
    def get_data(self):
        return self.data  # Читаем переменную

processor = DataProcessor("ETL")
processor.load_data()
print(processor.get_data())  # [1, 2, 3]

Переменные класса (Class Variables)

Переменные класса — общие для всех экземпляров:

class Analytics:
    total_events = 0  # Переменная класса
    
    def __init__(self, event_name):
        self.event_name = event_name  # Переменная экземпляра
        Analytics.total_events += 1  # Используем переменную класса
    
    @classmethod
    def get_total_events(cls):
        return cls.total_events  # Обращение через cls

evt1 = Analytics("click")
evt2 = Analytics("view")
print(Analytics.get_total_events())  # 2
print(Analytics.total_events)  # 2

Переменные с префиксом (приватные и защищённые)

Одно подчёркивание (_var) — защищённая переменная (по соглашению):

class Database:
    def __init__(self, host):
        self._host = host  # Защищённая переменная
        self.__password = "secret"  # Приватная переменная
    
    def get_host(self):
        return self._host

db = Database("localhost")
print(db._host)  # Работает, но "не рекомендуется"
print(db.__password)  # AttributeError!

Двойное подчёркивание (__var) — приватная переменная (name mangling):

class SecureProcessor:
    def __init__(self):
        self.__token = "abc123xyz"
    
    def show_token(self):
        print(self.__token)

sp = SecureProcessor()
sp.show_token()  # Работает
print(sp.__token)  # AttributeError!
print(sp._SecureProcessor__token)  # Работает (name mangling)

Обращение к вложенным атрибутам

class Config:
    def __init__(self):
        self.database = {"host": "localhost", "port": 5432}
        self.cache = CacheConfig()

class CacheConfig:
    def __init__(self):
        self.redis_url = "redis://localhost:6379"

config = Config()
print(config.database["host"])  # localhost
print(config.cache.redis_url)  # redis://localhost:6379

Динамическое обращение к переменным

getattr() и setattr() для динамического доступа:

class Pipeline:
    def __init__(self):
        self.stage1_status = "pending"
        self.stage2_status = "pending"
        self.stage3_status = "pending"
    
    def update_stage(self, stage_num, status):
        # Динамический доступ к атрибуту
        attr_name = f"stage{stage_num}_status"
        setattr(self, attr_name, status)
    
    def get_stage_status(self, stage_num):
        attr_name = f"stage{stage_num}_status"
        return getattr(self, attr_name, "unknown")

pipeline = Pipeline()
pipeline.update_stage(1, "running")
pipeline.update_stage(2, "completed")
print(pipeline.get_stage_status(1))  # running
print(pipeline.get_stage_status(2))  # completed

vars() и dict для инспекции

class Job:
    def __init__(self, job_id, status):
        self.job_id = job_id
        self.status = status

job = Job("job_123", "pending")

# Получить все переменные экземпляра
print(vars(job))  # {job_id: job_123, status: pending}
print(job.__dict__)  # То же самое

# Итерировать по переменным
for attr_name, attr_value in vars(job).items():
    print(f"{attr_name} = {attr_value}")

Параметры функций (аргументы)

Позиционные и именованные параметры:

def extract_data(source, destination, chunk_size=1000, overwrite=False):
    print(f"Источник: {source}")  # Позиционный аргумент
    print(f"Размер чанка: {chunk_size}")  # Параметр со значением по умолчанию

extract_data("S3", "DWH")  # chunk_size = 1000
extract_data("S3", "DWH", chunk_size=5000)  # Именованный аргумент
extract_data("S3", "DWH", 5000, True)  # Позиционные

**Распаковка переменных (*args, kwargs):

def log_metrics(*args, **kwargs):
    # *args — кортеж позиционных аргументов
    for arg in args:
        print(f"Метрика: {arg}")
    
    # **kwargs — словарь именованных аргументов
    for key, value in kwargs.items():
        print(f"{key} = {value}")

log_metrics(10, 20, 30, cpu=85, memory=60)
# Метрика: 10
# Метрика: 20
# Метрика: 30
# cpu = 85
# memory = 60

Переменные в lambda функциях

multiplier = 10

# lambda имеет доступ к внешней переменной
process = lambda x: x * multiplier
print(process(5))  # 50

# Список lambda с захватом переменной (ошибка)
functions = []
for i in range(3):
    functions.append(lambda x: x + i)  # i захватывается неправильно!

print([f(10) for f in functions])  # [12, 12, 12] вместо [10, 11, 12]

# Исправление: использовать параметр по умолчанию
functions_fixed = []
for i in range(3):
    functions_fixed.append(lambda x, i=i: x + i)  # Правильно!

print([f(10) for f in functions_fixed])  # [10, 11, 12]

Переменные в контексте (контекстные менеджеры)

class DatabaseContext:
    def __init__(self, connection_string):
        self.connection_string = connection_string
        self.connection = None
    
    def __enter__(self):
        # Переменная доступна в контексте with
        self.connection = f"Connected to {self.connection_string}"
        return self.connection
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.connection = None

with DatabaseContext("postgres://localhost") as conn:
    print(conn)  # Connected to postgres://localhost

print(conn)  # Переменная всё ещё существует, но соединение закрыто

Best Practices

# ✅ Используй имена переменных ясные и описательные
stage_count = 5  # Хорошо
sc = 5  # Плохо

# ✅ Используй snake_case для переменных
user_name = "Alice"  # Правильно
userName = "Alice"  # Неправильно (CamelCase для классов)

# ✅ Избегай глобальных переменных, используй параметры
# ❌ Плохо
global_data = [1, 2, 3]
def process():
    global global_data
    global_data.append(4)

# ✅ Хорошо
def process(data):
    data.append(4)
    return data

# ✅ Используй type hints для ясности
def calculate_metric(value: int, threshold: float) -> bool:
    return value > threshold

Выводы

В Python есть несколько способов обращения к переменным:

  • Локальные — внутри функции
  • Глобальные — на уровне модуля
  • self. — переменные экземпляра
  • Класс. — переменные класса
  • getattr/setattr — динамический доступ
  • _protected, __private — соглашения о видимости

Выбор способа зависит от контекста и нужной области видимости переменной.

Как обращаться к переменным? | PrepBro