Lets say you have a structure of files that looks like this:
/python/ /python/start_server.py /python/server/ /python/server/__init__.py /python/server/request_handler.py - Lets say we define a RequestHandler class in here. /python/server/conn/ /python/server/conn/__init__.py /python/server/conn/listener.py - Lets say we define a Listener class in here.
The first directory
python is optional. I used it in this example in
case you had a multiple project or multiple language checkout and wanted to
keep your python bits separate.
If this is not the case you can pretend like the python dir doesn't exist at all and this should still work out the same.
Our code starts inside of the
python directory so this will be the root
of this project.
The subdirectories naturally make python
modules. So from python's point of view
we have the following modules.
server server.request_handler server.conn server.conn.listener
We have the following classes.
start_server.py I might do something like:
from server.conn.listener import Listener if __name__ == '__main__': Listener().start_listening()
Keep this in mind as we go further.
Think of when you are creating a class and if you want your object
to execute some code at the beginning you put the code in the
For example, the Listener class almost certainly has a method called
__init__(self) and it gets
called when we instantiate Listener.
__init__.py files are essentially the same thing except for modules.
Imagine if the
server.conn module was a class. Its
__init__(self) would be the
These files can (and frequently are) completely empty. But here is an example of how they work.
If I were to add to the file
/python/server/conn/__init__.py the following code:
some_kind_of_variable = 'Yahoo!'
In other code I could do this:
from server.conn import some_kind_of_variable print(some_kind_of_variable)
By mentioning 'server.conn' it was like instantiating that module and everything within
/python/server/conn/__init__.py was executed
within that module's scope. Since we created a variable
some_kind_of_variable it is now available within that module.
We could also do:
Any time you are one or more subdirectories in from the base of the python project and you intend to import python code from there.
In the initial example we had an additional
/python folder that wasn't part of the project so it did not need an
file in it.
We did, however, intend to import from
server, so it needed to have a
__init__.py file in it.
Here is another example of paths with examples of where NOT to use
__init__.py. In this case our code is intended to be
ran from the root instead of a separate
/start_the_importer.py /core/ /core/__init__.py /core/file_handling.py /importer/ /importer/__init__.py /importer/the_icky_file_importer.py /tests/ /tests/__init__.py /tests/core/ /tests/core/__init__.py /tests/core/test_file_handling.py /tests/importer/ /tests/importer/__init__.py /tests/importer/test_the_icky_file_importer.py /docs/ /docs/README.md /html/ /html/status_page.html
You will note that there is NOT a
/__init__.py file. Since this is the base of the python code, we are not yet in a module
and so we don't need an
We do intend to import code from
tests.importer. All of
those folders get their own
__init__.py files. In these cases, those files are completely empty.
This allows python to see that it can import from these modules but the modules themselves don't need any special code.
Last, you will notice that
/html do not continain
__init__.py files. That is because they are not intended
to be python modules and therefore don't need them.