Почему вывод программы — "B B True" в этом синглтоне
@python_quizРазберем этот квиз
Кратко: код реализует одиночку (singleton) через переопределение __new__, но __init__ выполняется при каждом создании, поэтому поле name перезаписывается. В результате оба объекта — один и тот же экземпляр с именем из последнего вызова.
Исходный код (упорядоченный для удобства)

Разбор по шагам
- При первом вызове Service('A'):
- Python вызывает __new__(Service, 'A'). Внутри __new__ нет атрибута _inst у Service, значит выполняется правая часть выражения:
- setattr(cls, '_inst', object.__new__(cls)) — создаёт новый объект и сохраняет его в Service._inst. Функция setattr возвращает None.
- Затем используется or cls._inst, поэтому итогом выражения становится созданный экземпляр.
- __new__ возвращает этот единственный экземпляр.
- Затем вызывается Service.__init__(экземпляр, 'A'), записывается self.name = 'A'.
- При втором вызове Service('B'):
- __new__(Service, 'B') видит, что Service._inst уже существует, поэтому сразу возвращает этот же экземпляр.
- Python всё равно вызывает __init__ на возвращённом экземпляре (поведение CPython: если __new__ возвращает экземпляр того же класса, __init__ вызывается), и __init__ снова выполняет self.name = 'B', перезаписывая имя.
- Итог:
- s1 и s2 — тот же объект (s1 is s2 -> True).
- Атрибут name у этого объекта равен 'B' (последняя инициализация), значит печать выдаёт: B B True
Почему используется такой трюк в __new__?
Выражение

работает так:
- getattr возвращает экземпляр, если он уже есть;
- иначе выполняется второй операнд: setattr сохранит созданный объект в атрибут и вернёт None, поэтому
None or cls._instвернёт только что записанный экземпляр.
Это компактная (но не самая читаемая) идиома для ленивого создания единственного экземпляра.
Анализ вариантов ответов (почему какие-то неверны)
- "A B False" — неверно, потому что
__new__гарантирует один экземпляр, значит s1 is s2 не может быть False. - "A B True" — неверно, потому что если s1 и s2 — один объект, то поле name будет перезаписано последним
__init__и оба будут иметь значение 'B', а не 'A B'. - "B B True" — совпадает с объяснением: один экземпляр, имя из последнего вызова.
- "B A True" — неверно, порядок имён противоречит последовательности вызовов и перезаписи: второе создание задаёт 'B', оно переопределит 'A'.
Как сделать поведение более очевидным или «безопасным»?
Если цель — чтобы инициализация выполнялась только при первом создании, есть несколько подходов.
1) Защитить __init__ флагом:

2) Реализовать singleton через метакласс (более питонично):

Здесь __call__ метакласса контролирует создание: __init__ будет вызван только при первом создании, потому что при создании экземпляра мы используем super().__call__ (который вызывает __new__ и __init__) только один раз.
3) Использовать фабрику/декоратор — иногда проще и явнее, чем переопределение магических методов.
Вывод
Код реализует singleton через переопределение __new__. Поскольку __init__ вызывается при каждом вызове конструктора, состояние экземпляра может перезаписываться — это ключ к пониманию вывода программы. Если нужно, чтобы инициализация происходила только единожды, стоит явно защитить __init__ или использовать метакласс/декоратор для управления созданием экземпляра.