title: Create multiple classes that do nothing with the purpose of distinguishing objects in Python
body: <p>In my organization I came across versions of the following code:</p>
  <pre class="lang-py prettyprint-override"><code>from abc import ABC
  
  
  class Animal(ABC):
      def __init__(self, name=&quot; &quot;):
          self.name = name
  
  
  class Dog(Animal):
      pass
  
  
  class Cat(Animal):
      pass
  
  
  class Fish(Animal):
      pass
  
  collection: list[Animal] = [
      Dog(),
      Cat(),
      Fish(),
  ]
  
  </code></pre>
  <p>The intended purpose (there might be other intentions as well) of this is to have the IDE (VSCode) have type hints for the various objects. However, we will have many <code>Animal</code>s and none of the derived classes implements any features.
  Wouldn't this follow DRY more closely:</p>
  <pre class="lang-py prettyprint-override"><code>class Animal:
      def __init__(self, type, name=&quot; &quot;):
          self.type = type
          self.name = name
  
  
  collection: list[Animal] = [
      Animal(type=&quot;Dog&quot;),
      Animal(type=&quot;Cat&quot;),
      Animal(type=&quot;Fish&quot;),
  ]
  
  </code></pre>
  <p>I do understand that the second implementation has the downside of allowing for arbitrary arguments for <code>type</code>, maybe this could be avoided?</p>
  <p>What's the right way to go about this? How to deal with a situation where classes are just existing to name things? Is this best practice?</p>