Каков прецедент для метода __new__ для возврата объекта другого типа, чем его первый аргумент?

Документация подразумевает, что для __new__(cls, ...) это нормально __new__(cls, ...) чтобы возвращать объект типа, отличного от cls . В этом случае __init__() не будет вызываться. Это не указано явно, но здравый смысл или простой тест подтверждает, что в результате объект не будет иметь тип cls .

Почему это, казалось бы, странное поведение допустимо? Какой прецедент? Это явно преднамеренно.

2 Solutions collect form web for “Каков прецедент для метода __new__ для возврата объекта другого типа, чем его первый аргумент?”

Это может быть полезно при создании макетных объектов для модульного тестирования.

Вы можете изменить метод __new__ чтобы вернуть в определенных случаях другой объект с тем же интерфейсом, что и оригинал (например, имитируя поведение экземпляров исходного класса), без изменений остальной части кода.

Я думаю, что люди Python просто решили, что нет причин принуждать __new__(cls, ...) возвращать экземпляры cls . __new__ – довольно продвинутый метод, поэтому пользователь, вероятно, знает, что делает, и могут быть некоторые причины использовать это поведение.

Тем не менее, они все равно должны сделать чек. Во время создания экземпляра следует вызывать __init__ . Это разумно, если экземпляр (возвращаемый с __new__ ) действительно является cls . Если __new__ возвращает что-то другое, есть вероятность, что объект не сможет обработать аргументы, которые будут переданы __init__ .

В итоге добавление __new__ к языку оставило разработчикам три варианта:

  1. Enforce __new__(cls, ...) чтобы вернуть экземпляр cls
  2. Всегда вызывайте __init__ в экземпляре, возвращаемом __new__ , оставляя его пользователю, чтобы гарантировать, что объект может обрабатывать аргументы.
  3. __init__ только __init__ если экземпляр действительно является экземпляром cls .

Я думаю, что вариант 3 казался наиболее практичным.

  • TypeError: object () не принимает параметров
  • объект привязанного и несвязанного метода python
  • Python: Идиоматические свойства для структурированных данных?
  • Получение имени экземпляра внутри класса __init __ ()
  • Почему или скорее, как объект .__ new__ работает по-разному в этих двух случаях
  • a == b является ложным, но id (a) == id (b) истинно?
  • Почему Python не вызывает метод экземпляра __init __ () при создании экземпляра, но вызывает вместо него класс __init __ ()?
  • Как передать дополнительный аргумент при создании объекта, который использует синтаксис ** (двойной звезды) в python?
  • Python - лучший язык программирования в мире.