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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to