title: Python - why can I import modules without __init__.py at all?
body: <p>I'm new to Python and I still can't get my head around why we need a <code>__init__.py</code> file to import modules. I have gone through other questions and answers, such as <a href="https://stackoverflow.com/questions/448271/what-is-init-py-for">this</a>.</p>
  
  <p>What confuses me is that I can import my modules <strong>without</strong> <code>__init__py</code>, so <strong>why do I need it at all</strong>?</p>
  
  <p>My example,</p>
  
  <pre><code>index.py
     modules/
        hello/
            hello.py
            HelloWorld.py
  </code></pre>
  
  <p>index.py,</p>
  
  <pre><code>import os
  import sys
  
  root = os.path.dirname(__file__)
  sys.path.append(root + "/modules/hello")
  
  # IMPORTS MODULES
  from hello import hello
  from HelloWorld import HelloWorld
  
  def application(environ, start_response):
  
      results = []
  
      results.append(hello())
  
      helloWorld = HelloWorld()
      results.append(helloWorld.sayHello())
  
      output = "&lt;br/&gt;".join(results)
  
      response_body = output
  
      status = '200 OK'
  
      response_headers = [('Content-Type', 'text/html'),
                         ('Content-Length', str(len(response_body)))]
  
      start_response(status, response_headers)
  
      return [response_body]
  </code></pre>
  
  <p>modules/hello/hello.py,</p>
  
  <pre><code>def hello():
      return 'Hello World from hello.py!'
  </code></pre>
  
  <p>modules/hello/HelloWorld.py,</p>
  
  <pre><code># define a class
  class HelloWorld:
      def __init__(self):
          self.message = 'Hello World from HelloWorld.py!'
  
      def sayHello(self):
          return self.message
  </code></pre>
  
  <p>Result,</p>
  
  <pre><code>Hello World from hello.py!
  Hello World from HelloWorld.py!
  </code></pre>
  
  <p>What it takes is just these two lines,</p>
  
  <pre><code>root = os.path.dirname(__file__)
  sys.path.append(root + "/modules/hello")
  </code></pre>
  
  <p>Without any of <code>__init__py</code>. Can someone explain why it works in this way? </p>
  
  <p>If <code>__init__py</code> is the proper way, what should I do/change in my code?</p>