The isinstance() function

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.

Maintenance problem

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.

Solution 1: Easier to ask forgiveness than permission

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.

Solution 2: Leave it to the dispatcher

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.

Solution 3: Visitor class

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.

Read more

#python