Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set an object's superclass at __init__?

Tags:

python

oop

Is it possible, when instantiating an object, to pass-in a class which the object should derive from?

For instance:

class Red(object):
    def x(self):
        print '#F00'

class Blue(object):
    def x(self):
        print '#00F'

class Circle(object):
    def __init__(self, parent):
        # here, we set Bar's parent to `parent`
        self.x()

class Square(object):
    def __init__(self, parent):
        # here, we set Bar's parent to `parent`
        self.x()
        self.sides = 4

red_circle = Circle(parent=Red)
blue_circle = Circle(parent=Blue)
blue_square = Square(parent=Blue)

Which would have similar effects as:

class Circle(Red):
    def __init__(self):
        self.x()

without, however, affecting other instances of Circle.

like image 949
Phillip B Oldham Avatar asked Dec 08 '09 14:12

Phillip B Oldham


People also ask

What does super () __ init __ do?

Understanding Python super() with __init__() methods When this method is called it allows the class to initialize the attributes of the class. In an inherited subclass, a parent class can be referred with the use of the super() function.

Does super () init have to be first?

If the class you're super ing requires the object to be in a certain state then you put it in that state before super ... If your class requires the object to be in a certain state before it can continue its initialisation and that's provided by a parent class then you super that first.

What does __ init __ do in Python?

The __init__ method is the Python equivalent of the C++ constructor in an object-oriented approach. The __init__ function is called every time an object is created from a class. The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.

How does super () work in Python?

The super() function in Python makes class inheritance more manageable and extensible. The function returns a temporary object that allows reference to a parent class by the keyword super. The super() function has two major use cases: To avoid the usage of the super (parent) class explicitly.


2 Answers

Perhaps what you are looking for is a class factory:

#!/usr/bin/env python
class Foo(object):
    def x(self):
        print('y')

def Bar(parent=Foo):
    class Adoptee(parent):
        def __init__(self):
            self.x()
    return Adoptee()
obj=Bar(parent=Foo)
like image 126
unutbu Avatar answered Sep 21 '22 01:09

unutbu


I agree with @AntsAasma. You should probably consider using dependency injection. Atleast in the example given (which I'm sure is greatly simplified to illustrate your problem), the color of a shape is better represented by via a has-a relationship rather than with a is-a relationship.

You could implement this via passing in the desired color object to the constructor, storing a reference to it, and delegating the function call to this object. This greatly simplifies the implementation while still retaining the desired behavior. See an example here:

class Red(object):
    def x(self):
        print '#F00'

class Blue(object):
    def x(self):
        print '#00F'

class Shape(object):
    def __init__(self,color):
        self._color=color
    def x(self):
        return self._color.x()

class Circle(Shape):
    def __init__(self, color):
        Shape.__init__(self,color)
        self.x()

class Square(Shape):
    def __init__(self, color):
        Shape.__init__(self,color)
        self.x()
        self.sides = 4

red_circle = Circle(color=Red())
blue_circle = Circle(color=Blue())
blue_square = Square(color=Blue())

Edit: Fixed names of constructor arguments in sample code

like image 22
Mark Roddy Avatar answered Sep 22 '22 01:09

Mark Roddy