title: SOLID Principles and Imports in Python
body: <p><em>I frequently have this problem.</em></p>
  <p>In my projects I have some user input that controls the flow of the code.</p>
  <p>So let's say that the user will choose if the <strong>Fruit</strong> will be <strong>banana</strong> or <strong>apple</strong> and the code will do the right job.</p>
  <p>I try to apply SOLID Principles in my code.</p>
  <p>So I make a <code>Juicable</code> Interface for the fruits that will give me juice.</p>
  <pre class="lang-py prettyprint-override"><code>
      # fruits/juicable.py
      
      from abc import ABC, abstractmethod
      
      class Juicable(ABC):
          @abstractmethod
          def squeeze(self):
              pass
  </code></pre>
  <p>Now I make my fruit in a file called banana.py</p>
  <pre class="lang-py prettyprint-override"><code>    # fruits/banana.py
  
      from fruits.juicable import Juicable
  
      class Banana(Juicable):
          def squeeze(self):
              print('Banana juice in the glass')
  </code></pre>
  <p>And I make another fruit in a file called apple.py</p>
  <pre class="lang-py prettyprint-override"><code>    # fruits/apple.py
  
      from fruits.juicable import Juicable
  
      class Apple(Juicable):
          def squeeze(self):
              print('Apple juice in the glass')
  </code></pre>
  <p>Of course all fruits that make juice will implement the Juicable Interface.</p>
  <p>In another file I want to make juice.</p>
  <pre class="lang-py prettyprint-override"><code>    # bar/bartender.py
      
      from fruits.juicable import Juicable    
  
      def make_juice(fruit: Juicable):
          fruit.squeeze
  </code></pre>
  <h1>The problem</h1>
  <p>Based on user input, I usually import programmatically the correct Python module.</p>
  <p>ex. <code>fruits/banana.py</code> if the user chooses <strong>banana</strong>, I make a <code>Banana()</code> and call <code>make_juice()</code> from the <code>bar/bartender.py</code></p>
  <h2>The first problem</h2>
  <p>is here because if I <strong>build the program</strong> as executable, there are no files... so it does not work.</p>
  <p>To solve the problem I import all <strong>Juicables</strong> and just call the right one based on user's input.</p>
  <p>But this breaks the <strong>Dependency Inversion Principle</strong></p>
  <blockquote>
  <p>High-level modules should not depend on low-level modules. Both should depend on abstractions.</p>
  </blockquote>
  <p>Right?</p>
  <p>By adding</p>
  <pre class="lang-py prettyprint-override"><code>    from fruits.banana import banana
      from fruits.apple import apple
  </code></pre>
  <p>To a higher level module, you need to update the module every time you add a new <strong>Juicable</strong></p>
  <p>Which also breaks the <strong>Single Responsibility Principle</strong>.</p>
  <h2>The second problem</h2>
  <p>appears when I want to list all <strong>Juicables</strong> to the user to choose.</p>
  <p><strong>First</strong> I list all <strong>juicables</strong> with <code>os.listdir</code> because I know they are in the <strong>fruits</strong> directory. ( And it seems just wrong! )</p>
  <p><strong>Then</strong> there is the same problem with no1. If I make an executable, there are no files. So I need again to import every one of them from a Higher-level module. And call <code>__subclasses__()</code> from <code>Juicable</code> class to find all Juicables.</p>
  <h1>The solution</h1>
  <p>In other languages you just call a similar <code>subclasses()</code> method and you are good to go but I don't know how imports work in other languages.</p>
  <p>In Python. You need to <strong>import</strong> the file and load all <code>Juicables</code> first so later you can <strong>call</strong> a method to get you all subclasses <em>( all classes that implement the interface )</em>.</p>
  <p>But I want to know what are my subclasses to import them.</p>
  <p><strong>Is there a design flaw?</strong></p>
  <p><strong>Where do I lose it?</strong></p>
  <p><strong>Would it be better if somehow I import * <strong>blindly</strong>? And how is this done the right way?</strong></p>