2001 Enchancement Wishlist
Pearu Peterson
pearu at cens.ioc.ee
Sat Dec 30 03:52:10 EST 2000
On Fri, 29 Dec 2000, Raymond Hettinger wrote:
> 3. __init__ is the only special method that doesn't allow a return value.
> I think it should continue to return the new object by default but also
> allow another return item to be substituted. For example:
>
> def __init__( self ):
> if MyClass.aSingleton == None:
> MyClass.aSingleton = self
> return MyClass.aSingleton
I see that many Python experts are against this proposal but anyway, I
would like to support this idea with the following examples.
Say, I would like to define
class Real:
def __init__(self,num):
self.num = num
<other number class methods>
class Complex:
def __init__(self,real,imag):
if imag == 0:
return Real(real)
self.real,self.imag = real,imag
<other number class methods>
That is, if imaginary part of a Complex number is zero, it's constructor
would return Real instance:
>>> a = Complex(1,2)
>>> b = Complex(1,0)
>>> print a.__class__.__name__,b.__class__.__name__
Complex Real
Yes, I could cover this example in Python 2.0 by defining:
class Complex:
def __init__(self,real,imag):
if imag == 0:
self.__class__ = Real
self.real = real
else:
self.real,self.imag = real,imag
<other number class methods>
but it works only if __init__ should "return" a class instance.
For example, the following behavior cannot be handled in Python 2.0:
class NonZeroInteger:
def __init__(self,num):
if num == 0:
return 0
self.num = num
<other number class methods>
so that
>>> type(NonZeroInteger(2)),type(NonZeroInteger(0))
(<type 'instance'>, <type 'int'>)
Sure, one can write wrapper functions (as some of you already suggested):
class _Complex:
...
def Complex(real,imag):
if imag == 0: return Real(real)
return _Complex(real,imag)
but I think that this way is actually a very unpythonic one,
especially if there is much simpler/cleaner solution available (that is,
possible), that is, allowing __init__ return arbitrary object.
I have used these number classes only for demonstration, but there are
real situations where 'rich' __init__ would be very useful. For example,
in PySymbolic there are classes Plus, Symbol, etc and gmpy numbers that
are objects. E.g. class Plus represents a sum of its elements (arguments):
c = Plus(a,b,c) -> c = a + b + c # c is Plus instance
where a,b,c are Symbol instances.
Now, if one constructs a Plus instance only with one argument,
c = Plus(a) -> c = a # c is Symbol instance
***lots of code*** could be avoided with rich Plus.__init__ that would
return in this case Symbol instance a.
If the argument to Plus constructor is gmpy number:
c = Plus(mpz(3)) -> c = mpz(3) # c is mpz type object
then rich Plus.__init__ would return mpz object.
So, in my humble opinion, rich __init__ would be very useful feature.
Pearu
More information about the Python-list
mailing list