Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как создать переменную класса в Python
Переменные класса — это атрибуты, которые существуют на уровне класса и общие для всех экземпляров. Вот полное руководство.
Основное определение
# Переменная класса определяется прямо в теле класса
class Car:
# Переменная класса (общая для всех экземпляров)
wheels = 4
manufacturer = "Unknown"
def __init__(self, color):
# Переменная экземпляра (своя для каждого экземпляра)
self.color = color
# Доступ к переменной класса
print(Car.wheels) # 4 (через класс)
car1 = Car("red")
print(car1.wheels) # 4 (через экземпляр)
car2 = Car("blue")
print(car2.wheels) # 4 (у обоих одинаково)
print(car2.color) # "blue" (разные экземпляры)
Разница между переменными класса и экземпляра
class Student:
# Переменная класса
school_name = "Public School"
total_students = 0 # Считаем количество студентов
def __init__(self, name):
# Переменная экземпляра
self.name = name
Student.total_students += 1 # Инкрементируем счётчик класса
# Создаём студентов
student1 = Student("Alice")
student2 = Student("Bob")
student3 = Student("Charlie")
print(Student.total_students) # 3
print(Student.school_name) # "Public School"
print(student1.name) # "Alice" — переменная экземпляра
print(student1.school_name) # "Public School" — переменная класса
Важное правило: изменение переменной класса
class Config:
debug = False # Переменная класса
print(Config.debug) # False
# ⚠️ ОСТОРОЖНО: различие между чтением и записью
# 1. ЧТЕНИЕ переменной класса через экземпляр (OK)
config = Config()
print(config.debug) # False (берёт из класса)
# 2. ЗАПИСЬ через экземпляр создаёт переменную ЭКЗЕМПЛЯРА!
config.debug = True # Это НЕ меняет класс
print(config.debug) # True (у экземпляра)
print(Config.debug) # False (в классе осталось прежнее)
print(config.__dict__) # {'debug': True} — собственная переменная
# 3. ЗАПИСЬ через класс меняет для всех
Config.debug = True
print(Config.debug) # True
config2 = Config()
print(config2.debug) # True (новые экземпляры получат новое значение)
Практические примеры
Пример 1: Счётчик экземпляров
class Book:
total_books = 0 # Переменная класса
def __init__(self, title, author):
self.title = title
self.author = author
Book.total_books += 1 # Увеличить счётчик
@classmethod
def get_total_books(cls):
return cls.total_books
book1 = Book("1984", "Orwell")
book2 = Book("Brave New World", "Huxley")
book3 = Book("Fahrenheit 451", "Bradbury")
print(Book.get_total_books()) # 3
print(Book.total_books) # 3
Пример 2: Конфигурация приложения
class Database:
# Переменные класса — конфигурация
host = "localhost"
port = 5432
database_name = "mydb"
connections = [] # Список всех подключений
def __init__(self, user, password):
self.user = user # Переменная экземпляра
self.password = password
self.connection_id = len(Database.connections) + 1
Database.connections.append(self.connection_id)
def get_connection_string(self):
return f"postgresql://{self.user}@{Database.host}:{Database.port}/{Database.database_name}"
db1 = Database("admin", "secret1")
db2 = Database("user", "secret2")
print(Database.connections) # [1, 2]
print(db1.get_connection_string())
# postgresql://admin@localhost:5432/mydb
Пример 3: Версионирование класса
class APIClient:
version = "1.0.0"
api_key = None
def __init__(self, endpoint):
self.endpoint = endpoint # Переменная экземпляра
@classmethod
def set_api_key(cls, key):
"""Установить API ключ для всех экземпляров"""
cls.api_key = key
@classmethod
def get_version(cls):
return cls.version
# Установить глобальный API ключ
APIClient.set_api_key("sk-1234567890")
# Все экземпляры используют один API ключ
client1 = APIClient("https://api.example.com")
client2 = APIClient("https://api2.example.com")
print(client1.api_key) # "sk-1234567890"
print(client2.api_key) # "sk-1234567890" (общий)
print(APIClient.version) # "1.0.0"
Методы класса (classmethod) vs переменные класса
class User:
# Переменная класса
user_count = 0
def __init__(self, name):
self.name = name
User.user_count += 1
# Метод класса — может работать с переменными класса
@classmethod
def get_user_count(cls):
"""Получить количество созданных пользователей"""
return cls.user_count
@classmethod
def create_from_dict(cls, data):
"""Альтернативный конструктор"""
return cls(data['name'])
user1 = User("Alice")
user2 = User("Bob")
print(User.get_user_count()) # 2 — метод класса읽ает переменную класса
print(User.user_count) # 2 — прямой доступ
Мутируемые переменные класса (опасно!)
# ❌ ОПАСНО: изменяемые объекты как переменные класса
class BadDesign:
items = [] # Изменяемый объект!
def __init__(self, name):
self.name = name
BadDesign.items.append(name) # Изменяем список класса
obj1 = BadDesign("item1")
obj2 = BadDesign("item2")
print(BadDesign.items) # ["item1", "item2"] — список КЛАССА
print(obj1.items is BadDesign.items) # True — они один и тот же!
# Это может привести к неожиданным ошибкам
# ✅ ПРАВИЛЬНО: переменные экземпляра для изменяемых объектов
class GoodDesign:
def __init__(self, name):
self.name = name
self.items = [] # Переменная экземпляра — своя для каждого
obj1 = GoodDesign("item1")
obj2 = GoodDesign("item2")
obj1.items.append("a")
obj2.items.append("b")
print(obj1.items) # ["a"] — своя
print(obj2.items) # ["b"] — своя
print(obj1.items is obj2.items) # False — разные
Статические методы vs переменные класса
class Math:
# Переменная класса
PI = 3.14159
@staticmethod
def circle_area(radius):
"""Статический метод — не использует состояние класса"""
return Math.PI * radius ** 2
@classmethod
def get_constant(cls):
"""Метод класса — может использовать переменные класса"""
return cls.PI
print(Math.circle_area(5)) # 78.53975
print(Math.get_constant()) # 3.14159
Доступ через dict
class Example:
class_var = "class"
def __init__(self):
self.instance_var = "instance"
obj = Example()
# Переменные класса находятся в __dict__ класса
print(Example.__dict__.keys())
# dict_keys(['__module__', '__doc__', 'class_var', '__init__', '__dict__', '__weakref__'])
# Переменные экземпляра находятся в __dict__ экземпляра
print(obj.__dict__)
# {'instance_var': 'instance'}
# Но Python сначала ищет в экземпляре, потом в классе
print(obj.class_var) # "class" (найдётся в классе)
print(obj.instance_var) # "instance" (найдётся в экземпляре)
Type hints для переменных класса
from typing import ClassVar, List
class TypedExample:
# Обозначение переменной класса с типом
version: ClassVar[str] = "1.0.0"
registry: ClassVar[List[str]] = []
def __init__(self, name: str):
self.name: str = name # Переменная экземпляра
# IDE и type checker понимают, что это переменная класса
print(TypedExample.version)
print(TypedExample.registry)
Итоговые рекомендации
✅ Используй переменные класса для:
- Констант (версия, константы, конфигурация)
- Счётчиков (количество экземпляров)
- Регистров (список всех объектов)
- Конфигурации приложения
❌ Не используй переменные класса для:
- Изменяемых объектов (списков, словарей)
- Данных, уникальных для экземпляра
- Состояния экземпляра
✅ Правила:
- Определи переменную класса прямо в теле класса
- Обращайся через класс:
ClassName.variable - Для изменяемых данных используй переменные экземпляра
- Используй @classmethod для методов, работающих с переменными класса
- Используй ClassVar в type hints для явности