Previous: 29 - Comments and Code Documentation | Table of Contents | Next: 31 - Automated Testing
30 - Packages and Project structure
This section is low on code but introduces some powerful features of Python that will enable you to scale your code to do large, maintainable projects. Within the next few lessons you will be doing another project. This time your project will be object-oriented. You will use a class structure to do something interesting. You should start thinking about what you want to do right now. So far you have done a project in which you probably made a structure of global variables (i.e. variables that were defined outside of any function or class) and used functions to act on those variables. This project will focus on using the object-oriented features of Python to make the best and most robust piece of software that you can.
However, before we can write these larger codes we must learn how to structure projects to organize our code. The following exercise will walk you through building a basic structure for your project.
Building a Basic Project Structure
Go to your CLI, navigate to a place where you will build your project build the following project structure using the CLI commands you have learned. Enter the following commands:
For Linux and Mac:
$ mkdir emails
$ mkdir ./emails/emails ./emails/bin ./emails/docs ./emails/tests
$ touch ./emails/README.md
$ touch ./emails/emails/__init__.py ./emails/tests/__init__.py
$ touch ./emails/bin/placeholder.txt ./emails/docs/placeholder.txt
$ ls -R ./emails/
For windows:
> mkdir emails
> mkdir ./emails/emails
> mkdir ./emails/bin
> mkdir ./emails/docs
> mkdir ./emails/tests
> New-Item ./emails/README.md
> New-Item ./emails/emails/__init__.py
> New-Item ./emails/tests/__init__.py
> New-Item ./emails/bin/placeholder.txt
> New-Item ./emails/docs/placeholder.txt
> ls -R ./emails/
When you are done your structure should look like this:
./emails/:
emails
bin
docs
tests
README.md
./emails/bin:
placeholder.txt
./emails/docs:
placeholder.txt
./emails/emails:
__init__.py
./emails/tests:
__init__.py
The emails
package
You have just created project called emails
that contains two packages called emails
and tests
. Both of these packages contain an __init__.py
file. This file tells python to treat the file's containing folder as a Python module. Therefore, any code in ./emails/emails/__init__.py
may be imported from emails as: from emails import a_thing
where a_thing
is any class, function or variable defined inside of the __init__.py
script. Other Python scripts may be placed in the folder as well (regardless of the presence of an __init__.py
script) and classes functions or variables may be imported as: from emails.module import a_thing
where module
corresponds to module.py
inside the folder. The emails
folder is where we want to put all of our Python source code for the project. The tests
package is where we can write automated tests for our emails
package. We will work mainly with these two folders for this section.
The other two folders are bin
and docs
and contain binary or executable files we wish to include with our code and documentation about our code respectively. The structure we have just made is not the only or "correct" way to structure a project but it is a convenient way to start a project. For our purposes, it is a good idea not to have an empty folder so we have put a placeholder.txt
file in each empty folder.
Make a project
Now that we have our project 'skeleton' in place, copy your working code from the modules section into the emails
folder. Because you will run this in the context of the emails
package make sure you change the following imports to reflect this. Change:
from database_manager import DatabaseManager
to:
from emails.database_manager import DatabaseManager
This will ensure that you are importing from the right environment. If you are using your modules in a project structure you will need to make sure they are referenced correctly or your project will break.
Test your project by opening a python prompt in your project's root directory and executing the following commands:
$ pwd
.../path/to/project/emails/
$ python
Python 3.x.x ...
Type "help", "copyright", "credits" or "license" for more information.
>>> from emails.user_interface import run_ui_test
>>> run_ui_test()
Your project should run as it always has.
If the above test worked, congradulations! You have yourself a working project! You can add code to the emails
folder or documentation to the docs
folder as you see fit. But for our purposes, the real utiltiy of the project structure is the abliity you have to automatically test your project with automated tests.
This will be covered in the next section.
Hone Your Skills
- if you haven't already, now would be a good time to turn the documentation in your docstrings into a human readable manual. If you are unsure where to start, try using pydoc and invoke it by using
python -m pydoc
. (Enterpython --help
to get an idea of how this works). - Begin building your own project! Have an idea you want to implement? Start by building a similar project structure as above but replace every filename instance of
emails
with the name of your own project. Begin fleshing out what you want to see from this project.
Previous: 29 - Comments and Code Documentation | Table of Contents | Next: 31 - Automated Testing