ironstein
ironstein

Reputation: 547

Python : calling __new__ method of superclass

I have two python classes defined like follows :

class A(object) : 

    def __init__(self, param) : 
        print('A.__init__ called')
        self.param = param

    def __new__(cls, param) :
        print('A.__new__ called') 
        x = object.__new__(A)
        x._initialize()    # initialization code
        return x

class B(A) : 

    def __init__(self, different_param) : 
        print('B.__init__ called')

    def __new__(cls, different_param) : 
        print('B.__new__ called')
        # call __new__ of class A, passing "param" as parameter
        # and get initialized instance of class B
        # something like below
        b = object.__new__(B)
        param = cls.convert_param(different_param)
        return super(B, cls).__new__(b, param)    # I am expecting something
                                                  # similar to this

    @staticmethod
    def convert_param(param) : 
        return param 

class B is a subclass of class A. The difference between the two classes is that the parameters passed to class B are in a different format as compared to those expected by class A. So, the convert_param method of classB is called to convert the parameters to be compatible with the __new__ method of class A.

I am stuck at the part where I wish to call the __new__ method of class A from the __new__ method of class B, since there is a lot of initialisation that takes place in there, and then get back the initialised instance of class B.

I am having a difficult time figuring this out. Please help.

Upvotes: 0

Views: 1826

Answers (1)

mgilson
mgilson

Reputation: 309831

convert_param should either be a staticmethod or a classmethod and you don't want to be calling object.__new__ from B (otherwise, you're essentially trying to create two new instances of B instead of just one). If convert_param is a staticmethod or a classmethod, then you can do the parameter conversion before you have an instance (e.g. before __new__ has been called on the superclass):

class B(A):
    @staticmethod
    def convert_param(params):
        # do magic
        return params

    def __new__(cls, params):
        params = cls.convert_params(params)
        return super(B, cls).__new__(cls, params)

Additionally, you'll need to change A's __new__ slightly to not hard-code the type of the instance returned from object.__new__:

class A(object) : 
    def __new__(cls, param) :
        print('A.__new__ called') 
        x = super(A, cls).__new__(cls)
        x._initialize()    # initialization code
        return x

Upvotes: 2

Related Questions