return an object of a different class

Jean-Michel Pichavant jeanmichel at sequans.com
Thu Feb 17 14:38:21 CET 2011


Steven D'Aprano wrote:
> On Thu, 17 Feb 2011 12:02:28 +0100, Jean-Michel Pichavant wrote:
>
>   
>> Karim wrote:
>>     
>>> [snip]
>>>       
>>>> If you don't want to use a factory function I believe you can do this:
>>>>
>>>> class MyNumber(object):
>>>>      def __new__(cls, n):
>>>>          if n<= 100:
>>>>              cls = SmallNumbers
>>>>          else:
>>>>              cls = BigNumbers
>>>>          return object.__new__(cls, n)
>>>>      ...
>>>>
>>>> Chard.
>>>>         
>>> Very beautiful code great alternative to factory method! To memorize
>>> this pythonic way.
>>>
>>> Regards
>>> Karim
>>>       
>> Do you think  that the MyNumber constructor returning something else
>> than a MyNumber instance is the pythonic way ? It would rather be the
>> cryptonic way ! (haha)
>>     
>
>
> Support for constructors returning something other than an instance of 
> the class is not an accident, it is a deliberate, and useful, design. The 
> Fine Manual says:
>
>     object.__new__(cls[, ...])
>
>     Called to create a new instance of class cls. [...] 
>     The return value of __new__() should be the new object 
>     instance (usually an instance of cls).
>     [...]
>     If __new__() does not return an instance of cls, then 
>     the new instance’s __init__() method will not be invoked.
>
>
> http://docs.python.org/reference/datamodel.html#basic-customization
>
> So while it is *usual* for the constructor to return an instance of the 
> class, it's not compulsory, and returning other types is explicitly 
> supported.
>
> To answer your question about whether this is Pythonic... here's a small 
> clue from Python 2.5:
>
>   
>>>> n = int("4294967296")  # 2**32
>>>> type(n)
>>>>         
> <type 'long'>
>
>
>
> So, yes, absolutely, it is not only allowed for class constructors to 
> return an instance of a different class, but there is precedence in the 
> built-ins.
>
>   
Returning another class instance in a new operator is legit, but 
regarding the documentaiton you quoted, it's also "unusual", for which 
is used the word "cryptonic" instead. But that was only in the attempt 
of being clever. But I'm used to that when it comes to joking in english 
:-/.

Thing is, I said the same thing that the __new__ documentation.

Concerning the example you've given, you shoud notice that int and long 
objects have the exact same interface, same attributes. And all their 
methods mean to do the same thing. In fact it doesn't really matter if 
you're manipulating an int or a long, you're still using the 2 objects 
the same way for the same result. From a duck typing POV, they're the 
same class.
This is not what would happen for the OP, given the examples he gave.

JM



More information about the Python-list mailing list