Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the use case for __new__ method to return an object of a different type than its first arg?

The documentation implies that it's ok for __new__(cls, ...) to return an object of a type different than cls. It says in that case __init__() won't be called. It's not stated explicitly, but common sense or a simple test confirms that the resulting the object won't have type cls.

Why is this seemingly strange behavior allowed? What's the use case? It's clearly intentional.

like image 643
max Avatar asked Apr 18 '12 09:04

max


People also ask

What does the __ New__ method do in Python?

Whenever a class is instantiated __new__ and __init__ methods are called. __new__ method will be called when an object is created and __init__ method will be called to initialize the object. In the base class object , the __new__ method is defined as a static method which requires to pass a parameter cls .

What should __ new __ return?

__new__ returns a instance of class. __init__ receives the instances of the class returned by __new__ . Use __init__ to initilize value.

What is __ class __ in Python?

__class__ is an attribute on the object that refers to the class from which the object was created. a. __class__ # Output: <class 'int'> b. __class__ # Output: <class 'float'> After simple data types, let's now understand the type function and __class__ attribute with the help of a user-defined class, Human .

When a new instance of class is created which method gets called?

The constructor method is a special method for creating and initializing an object created with a class . There can only be one special method with the name "constructor" in a class.


2 Answers

It can be useful when you create mock objects for unit testing.

You can change the __new__ method to return, in the certain cases, the the other object with the same interface, as original (for example simulating the original class instances' behaviour), without modifications to the rest of code.

like image 132
Rafał Rawicki Avatar answered Oct 23 '22 03:10

Rafał Rawicki


I guess the Python folks just decided that there is no reason to enforce __new__(cls, ...) to return instances of cls. __new__ is a fairly advanced method, so the user probably knows what he's doing, and there could be some reasons to exploit this behavior.

They still have to do the check, though. During instance creation, __init__ should be called. This is only reasonable if the instance (returned from __new__) really is a cls. If __new__ returns something different, chances are that the object cannot handle the arguments that would be passed to __init__.

In the end, the addition of __new__ to the language left the developers with three choices:

  1. Enforce __new__(cls, ...) to return an instance of cls
  2. Always call __init__ on the instance returned by __new__, leaving it up to the user to ensure that the object can handle the arguments.
  3. Only call __init__ if the instance really is an instance of cls.

I guess that option 3 seemed most practical.

like image 27
Ferdinand Beyer Avatar answered Oct 23 '22 02:10

Ferdinand Beyer