---
tags: Python
---
# Polymorphism in Python using `__new__`
author: [`ngokchaoho`](https://github.com/ngokchaoho)
Polymorphism is good. It makes life easier to have common interface. It is implemented often with inheritance where we have a super class with default behaviours and its child classes overriding those bahaviours. Then you can create instances usig those child classes while using the same set of methods.
Taking example from https://www.programiz.com/python-programming/polymorphism
```python=
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(f"I am a cat. My name is {self.name}. I am {self.age} years old.")
def make_sound(self):
print("Meow")
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(f"I am a dog. My name is {self.name}. I am {self.age} years old.")
def make_sound(self):
print("Bark")
cat1 = Cat("Kitty", 2.5)
dog1 = Dog("Fluffy", 4)
for animal in (cat1, dog1):
animal.make_sound()
animal.info()
animal.make_sound()
```
Now for whatever reason (e.g. you want to let the super class handle the import of the subclass instead of letting the developer/user to find the subclass and call it, you can implement an exception machanism so that the user know for sure that this type doesn't exist and not because of the user cannot find the subclass), you want to use the same instance constructor every time, what can you do? Is there a way to construct a child class intance through its super class?
The answer is yes! Using `__new__` as a constructor of the new instance, you can construct and return the subclass instance and later handled by `__init__` of class that comes first in the mro(if not implemented then the superclass's __init__is used)
```python=
class Animal:
def __new__(cls,type):
print(cls)
if (type=='dog'):
return super().__new__(Dog)
else:
raise AttributeError("This type is not implemented")
def __init__(self,type):
self.id = 0
def sound(self):
# to be implemented in subclass
pass
class Dog(Animal):
def __init__(self,type):
self.id = 1
def sound(self):
print('bark')
d = Animal(type='dog')
d.sound()
print(type(d))
print(d.__class__.__mro__)
print(d.id)
print('==============')
c = Animal(type='cat')
c.sound()
```
Output:
```
<class '__main__.Animal'>
bark
<class '__main__.Dog'>
(<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>)
1
==============
<class '__main__.Animal'>
Traceback (most recent call last):
File "<string>", line 29, in <module>
File "<string>", line 9, in __new__
AttributeError: This type is not implemented
```