Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Способы обращения к переменным в 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 — соглашения о видимости
Выбор способа зависит от контекста и нужной области видимости переменной.