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