2001 Enchancement Wishlist

Jeff Epler jepler at inetnebr.com
Sat Dec 30 13:43:04 EST 2000


On Sat, 30 Dec 2000 10:52:10 +0200, Pearu Peterson
>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:

I think that this can be accomplished by using a 'transmute' function, defined
something like the following:
	def transmute(instance, newclass, *args, **kw):
		instance.__class__ = newclass
		apply(instance.__init__, args, kw)
		return instance

it can be useful other places than __init__, for one thing.  See
Complex.__iadd__.

class Real:
	def __init__(self, num):
		self.num = num
	# numeric methods

class Complex:
	def __init__(self, real, imag=0):
		if not imag:
			transmute(self, Real, real)
			return
		self.real, self.imag = real, imag

	def __iadd__(self, other):
		self.real += other.real
		self.imag += other.imag
		if not self.imag:
			transmute(self, Real, self.real)
		return self
	# Other numeric methods

>>> complex(1,0)
<Real 1>
>>> c = complex(1,1)
>>> print c
<Complex 1+1i>
>>> c += complex(1,-1)
<Real 2>

Is there anything that you would like to do which transmute cannot?  One issue
I see is whether the dictionary should be cleared in the object before
it is transmuted (for instance, "c" still has attributes 'real' and
'imaginary' after it is transmuted in Complex.__iadd__) but I don't see
anything that is just plain impossible.

Toss transmute in your standard library somewhere, and you have a nice way to
write this code---just a function call.  Or make it a method on a common base
class.  I don't know whether "self.transmute(Real, self.real)" makes any more
or less sense than I wrote it above.

Jeff



More information about the Python-list mailing list