isinstance()
in Python code is usually a symptom
of bad abstractions. In a flow control fork, we can use
isinstance()
to identify the type of objects and
based on that treat them in different ways. But we ended up here
in the code because we are treating objects as they are of a
superclass type. This means that the superclass is not a
useful abstraction because it doesn’t provide enough information
to know what we can do with that object.
In other words, our classes implement the same interface but we treat them differently. The purpose of having an interface for abstractions is to describe how we can deal with them.
What happens when we add a new subclass to the superclass? We
need to revisit every isinstance()
call and check
how our new class should behave there.
If your control flow has just a handful of branches (happy path and exception), put it in a try block. This common Python coding style assumes the existence the existence of an attribute so we can handle special subclasses.
If you want to do something different depending on the type of the subclass, consider adding this code as a method in the subclasses. Define an abstract method, and have each subclass override this.
If you don’t believe that the action belongs to this class, consider the visitor pattern and separate the code. Create a visitor class, that implements all actions for the subclasses in specific methods. Superclass defines a method that accepts the visitor type so the subclasses can override this and call their respective method on the visitor.