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

Как создается экземпляр класса в Python?

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

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

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

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

Как создается экземпляр класса в Python

Создание экземпляра класса — это фундаментальный процесс в Python. Когда вы пишете obj = MyClass(), на самом деле происходит множество шагов. Давайте разберём этот процесс пошагово.

1. Простой пример и базовый процесс

class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age
    
    def greet(self):
        return f"Hello, I'm {self.name}"

# Создание экземпляра
person = Person("Alice", 30)

print(person.name)       # Alice
print(person.greet())    # Hello, I'm Alice
print(type(person))      # <class '__main__.Person'>
print(isinstance(person, Person))  # True

2. Процесс создания экземпляра (пошагово)

Когда вы вызываете Person("Alice", 30), происходит следующее:

Шаг 1: Вызов __new__ — выделение памяти

class Person:
    def __new__(cls, name: str, age: int):
        print(f"__new__ вызван для класса {cls.__name__}")
        # __new__ создаёт и возвращает новый экземпляр
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name: str, age: int):
        print(f"__init__ вызван для экземпляра")
        self.name = name
        self.age = age

person = Person("Alice", 30)
# __new__ вызван для класса Person
# __init__ вызван для экземпляра

Шаг 2: Инициализация через __init__

class Person:
    def __init__(self, name: str, age: int):
        print(f"Инициализация {name}")
        self.name = name
        self.age = age
        self.created_at = None  # Инициализируем атрибут

person = Person("Bob", 25)
# Инициализация Bob

Шаг 3: Возврат экземпляра

class Person:
    def __new__(cls, *args, **kwargs):
        instance = super().__new__(cls)
        print(f"Создан экземпляр: {instance}")
        return instance
    
    def __init__(self, name):
        self.name = name
        print(f"Инициализирован: {self.name}")

person = Person("Charlie")
# Создан экземпляр: <__main__.Person object at 0x...>
# Инициализирован: Charlie

3. Полный процесс с деталями

class Person:
    # Все люди одного вида
    species = "Homo sapiens"
    
    def __new__(cls, name: str, age: int):
        print(f"1. __new__: выделяется память для объекта класса {cls.__name__}")
        instance = super().__new__(cls)
        print(f"   Адрес памяти: {id(instance)}")
        return instance
    
    def __init__(self, name: str, age: int):
        print(f"2. __init__: инициализируются атрибуты экземпляра")
        self.name = name
        self.age = age
        self.email = None
    
    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age})"

print("Начало создания объекта...")
person = Person("Alice", 30)
print(f"Конец создания объекта.")
print(f"Объект: {person}")
print(f"Атрибут name: {person.name}")

# Вывод:
# Начало создания объекта...
# 1. __new__: выделяется память для объекта класса Person
#    Адрес памяти: 140296...
# 2. __init__: инициализируются атрибуты экземпляра
# Конец создания объекта.
# Объект: Person(name='Alice', age=30)
# Атрибут name: Alice

4. new vs init

class Example:
    def __new__(cls):
        print("__new__: создание нового объекта")
        return super().__new__(cls)
    
    def __init__(self):
        print("__init__: инициализация объекта")

# __new__ вызывается ПЕРЕД __init__
obj = Example()
# __new__: создание нового объекта
# __init__: инициализация объекта

# Если __new__ вернёт экземпляр другого класса, __init__ не вызовется
class Special:
    def __new__(cls):
        print("Возвращаю строку вместо экземпляра!")
        return "Not an instance"
    
    def __init__(self):
        print("__init__ не вызовется")

result = Special()
print(type(result))  # <class 'str'>

5. Singleton паттерн с new

class Singleton:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            print("Первое создание экземпляра")
            cls._instance = super().__new__(cls)
        else:
            print("Экземпляр уже существует")
        return cls._instance
    
    def __init__(self):
        self.id = id(self)

obj1 = Singleton()
# Первое создание экземпляра
obj2 = Singleton()
# Экземпляр уже существует

print(obj1 is obj2)  # True (один и тот же объект)
print(obj1.id)  # То же значение
print(obj2.id)  # То же значение

6. Создание с аргументами

class Rectangle:
    def __init__(self, width: float, height: float):
        self.width = width
        self.height = height
    
    def area(self) -> float:
        return self.width * self.height

# С позиционными аргументами
rect1 = Rectangle(5, 10)
print(rect1.area())  # 50

# С именованными аргументами
rect2 = Rectangle(width=3, height=4)
print(rect2.area())  # 12

# Смешанные
rect3 = Rectangle(7, height=8)
print(rect3.area())  # 56

7. Параметры со значениями по умолчанию

class Animal:
    def __init__(self, name: str, age: int = 0, species: str = "Unknown"):
        self.name = name
        self.age = age
        self.species = species

# Минимум аргументов
dog = Animal("Rex")
print(f"{dog.name}, {dog.age}, {dog.species}")  # Rex, 0, Unknown

# Переопределяем значения
cat = Animal("Whiskers", age=5, species="Cat")
print(f"{cat.name}, {cat.age}, {cat.species}")  # Whiskers, 5, Cat

8. **args и **kwargs

class FlexibleClass:
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        print(f"args: {args}")
        print(f"kwargs: {kwargs}")

# С разными аргументами
obj = FlexibleClass(1, 2, 3, name="Alice", age=30)
# args: (1, 2, 3)
# kwargs: {'name': 'Alice', 'age': 30}

9. Наследование и создание экземпляра

class Animal:
    def __init__(self, name: str):
        print(f"Animal.__init__: {name}")
        self.name = name

class Dog(Animal):
    def __init__(self, name: str, breed: str):
        print(f"Dog.__init__: {name}, {breed}")
        super().__init__(name)  # Вызываем родительский __init__
        self.breed = breed

dog = Dog("Rex", "Labrador")
# Dog.__init__: Rex, Labrador
# Animal.__init__: Rex

print(dog.name)   # Rex
print(dog.breed)  # Labrador

10. Метакласс — создание класса

class Meta(type):
    """Метакласс для контроля создания класса"""
    def __new__(mcs, name, bases, dct):
        print(f"Метакласс создаёт класс: {name}")
        return super().__new__(mcs, name, bases, dct)
    
    def __call__(cls, *args, **kwargs):
        print(f"Вызывается класс {cls.__name__}")
        instance = super().__call__(*args, **kwargs)
        print(f"Экземпляр создан: {instance}")
        return instance

class MyClass(metaclass=Meta):
    def __init__(self, value):
        self.value = value

obj = MyClass(42)
# Метакласс создаёт класс: MyClass
# Вызывается класс MyClass
# Экземпляр создан: <__main__.MyClass object at 0x...>

11. Порядок вызова при создании экземпляра

1. Python ищет класс в памяти
2. Вызывается __new__ класса
   2.1. Выделяется память
   2.2. Устанавливаются атрибуты класса
   2.3. Возвращается новый экземпляр
3. Если __new__ вернул экземпляр того же класса:
   - Вызывается __init__ для инициализации
4. Возвращается готовый экземпляр

12. Практический пример: Точка на координатной плоскости

import math

class Point:
    """Точка на двумерной плоскости"""
    
    total_points = 0  # Счётчик всех созданных точек
    
    def __new__(cls, x: float, y: float):
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y
        Point.total_points += 1
    
    def distance_from_origin(self) -> float:
        return math.sqrt(self.x ** 2 + self.y ** 2)
    
    def __repr__(self):
        return f"Point({self.x}, {self.y})"

point1 = Point(3, 4)
point2 = Point(1, 1)

print(point1)                          # Point(3, 4)
print(point1.distance_from_origin())   # 5.0
print(Point.total_points)              # 2

Вывод

Создание экземпляра состоит из:

  1. new — выделение памяти и создание объекта
  2. init — инициализация атрибутов экземпляра
  3. Возврат экземпляра вызывающему коду

Ключевые моменты:

  • __new__ — статический метод, создаёт объект
  • __init__ — вызывается только если __new__ вернул экземпляр того же класса
  • Порядок: __new____init__
  • Используйте __init__ для инициализации в 99% случаев
  • __new__ используется редко (Singleton, immutable типы, factory паттерны)

Этот процесс работает одинаково для всех классов в Python.

Как создается экземпляр класса в Python? | PrepBro