return an object of a different class

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Feb 17 06:43:47 EST 2011


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.



-- 
Steven



More information about the Python-list mailing list