return an object of a different class

MRAB python at mrabarnett.plus.com
Thu Feb 17 16:56:00 CET 2011


On 17/02/2011 14:39, Westley Martínez wrote:
> On Thu, 2011-02-17 at 11:43 +0000, 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.
>>
>>
>>
>> --
>> Steven
> Python 3 removed longs because they were ... cryptonic!
>
Strictly speaking, they weren't removed. ints were removed and long was
renamed int.



More information about the Python-list mailing list