izxle
izxle

Reputation: 405

Overwrite __init__ from a complex object

I want to have a custom complex class that can get a string as input ("1 2") and read the real and imag parts from there.

class myComplex(complex):
    def __init__(self, inp):
        real, imag = inp.split()
        self.real = float(real)
        self.imag = float(imag)


comp = myComplex("1 2")
print comp # (1+2j)

but I get the error:

Traceback (most recent call last):
  File "my_complex.py", line 8, in <module>
    comp1 = myComplex(inp1)
ValueError: complex() arg is a malformed string

does this mean that my __init__ is not overwritting the one from complex or am I missing something fundamental?

Upvotes: 4

Views: 87

Answers (1)

Fernando Matsumoto
Fernando Matsumoto

Reputation: 2727

Python's complex assigns the values of real and imag in __new__.

__new__ is run prior to __init__ and is responsible for the creation of the object. The execution (considering myComplex and complex) goes like this:

  1. myComplex("1 1")

  2. myComplex.__new__(cls, inp)

  3. complex.__new__(cls, real, imag)

  4. myComplex.__init__(self, inp)

(There is no complex.__init__ since myComplex.__init__ doesn't call it)

This means that the argument "1 2" is parsed before __init__ is run.

You should be overriding __new__:

class myComplex(complex):
    def __new__(cls, inp):
        real, imag = inp.split()
        return super(myComplex, cls).__new__(cls, float(real), float(imag))

Upvotes: 4

Related Questions