return an object of a different class
Jean-Michel Pichavant
jeanmichel at sequans.com
Thu Feb 17 08:38:21 EST 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