Переопределённый __init__ полностью заменяет родительский: Python не вызывает __init__
родителя сам. Объект создаётся только с download_url, а ошибка появляется позже —
при первом чтении name. super().__init__(...) выполняет инициализацию родителя,
и наследник дополняет её своим полем. По имени (Product.__init__(self, ...)) вызывать хуже:
при нескольких родителях это ломает порядок MRO.
Эталонное решение
from decimal import Decimal
class Product:
def __init__(self, name, price, stock):
self.name = name
self.price = price
self.stock = stock
def __str__(self):
return f"{self.name} — {self.price} ₽"
class DigitalProduct(Product):
def __init__(self, name, price, stock, download_url):
super().__init__(name, price, stock)
self.download_url = download_url
catalog = [
Product("Мышь", Decimal("1499.00"), 12),
DigitalProduct("Книга «Чистый код»", Decimal("690.00"), 100, "/download/42"),
]
for product in catalog:
print(product)