A SHORT PYTHON PRIMER
1
In this first chapter, we’ll take a look at some
of the Python features we’ll use throughout
the book. This is not meant to be an intro
duction to Python; I’m assuming you have a ba
sic understanding of the language. If you don’t, there
are plenty of good books and online tutorials that’ll
get you started.
We’ll first explore how Python code can be split into packages and how
to import these packages into our programs. We’ll learn how to document
Python code and how to consult this documentation using Python. Then,
we’ll review tuples, lists, sets, and dictionaries, which are the most popular
Python collections.
Python Packages and Modules
Software projects of a reasonable size usually consist of lots of source files,
also called modules. A coherent bundle of Python modules is referred to as
a package. Let’s start our discussion on Python by taking a look at these two
concepts: modules and packages.
Modules
A Python module is a file that contains Python code that’s meant to be im
ported by other Python modules or scripts. A script, on the other hand, is a
Python file that’s meant to be run.
Python modules allow us to share code between files, which spares us
from having to write the same code over and over again.
Every Python file has access to a global variable named __name__. This
variable can have two possible values:
• The name of the module, that is, the name of the file without the
.py extension
• The string '__main__'
Python determines the value of __name__ based on whether the file is im
ported by some other module or run as a script. When the module is im
ported inside another module or script, __name__ is set to the name of the
module. If we run the module as a script, for example,
$ python3 my_module.py
then the value of __name__ is set to '__main__'. This may seem a bit abstract
at the moment, but we’ll explain why we care about the __name__ global vari
able later in the chapter. As we’ll see, knowing if a given module is being
imported or run as a script is an important piece of information we’ll want
to consider.
As we write more and more Python modules for our project, it makes
sense to separate them into groups according to functionality. These groups
of modules are called packages.
Packages
A package is a directory containing Python modules and a special file whose
name is required to be __init__.py. Python’s interpreter will understand any
folder containing an __init__.py file as a package.
For instance, a folder structure like:
geom2d
|- __init__.py
|- point.py
|- vector.py
is a Python package called geom2d containing two files, or modules: point.py
and vector.py.
The __init__.py file is executed whenever something is imported from
the package. This means that the __init__.py file can contain Python code,
usually initialization code. Most of the time, however, this __init__.py file
remains empty.
4 Chapter 1
Running Files
When Python imports a file, it reads its contents. If this file contains only
functions and data, Python loads these definitions, but no code is actually
executed. However, if there are toplevel instructions or function calls, Python
will execute them as part of the import process—something we usually don’t
want.
Earlier, we saw how when a file is run (as opposed to imported), Python
sets the __name__ global variable to be the string '__main__'. We can use this
fact to execute the main logic only when the file is being run, and not when
the file is imported:
if __name__ == '__main__':
# only executes if file is run, not imported
We’ll refer to this pattern as the “if name is main” pattern, and we’ll use it in
the applications we’ll write in this book.
Remember that when a file is imported, Python sets the __name__ variable
to the name of that module.
Importing Code
Let’s say you had some Python code you wanted to use in multiple files. One
way to do that would be to copy and paste the code every time you wanted to
use it. Not only would this be tedious and boring, but imagine what would
happen if you changed your mind about how that code works: you’d need to
open every single file where you pasted the code and modify it in the same
way. As you can imagine, this is not a productive way of writing software.
Fortunately, Python provides a powerful system to share code: import
ing modules. When module_b imports module_a, module_b gains access to the
code written in module_a. This lets us write algorithms in a single place and
then share that code across files. Let’s look at an example using two mod
ules we’ll write in the next part of the book.
Say we have two modules: point.py and vector.py. Both modules are inside
the package we saw earlier:
geom2d
|- __init__.py
|- point.py
|- vector.py
The first module, named point.py, defines the geometric primitive Point,
and the second one, vector.py, defines the Vector, another geometric primi
tive. Figure 11 illustrates these two modules. Each module is divided into
two sections: a section in gray, for the code in the module that has been im
ported from somewhere else, and a section in white, for the code defined by
the module itself.
A Short Python Primer 5
Imported Imported
Self-defined Self-defined
Point Vector
point.py vector.py
module module
Figure 1-1: Two Python modules
Now, say we need our point.py module to implement some functional
ity that uses a Vector (like, for example, displacing a point by a given vector).
We can gain access to the Vector code in vector.py using Python’s import com
mand. Figure 12 illustrates this process, which brings the Vector code to the
“imported” section of the point.py module, making it available inside the en
tire module.
from vector import Vector
Imported Imported
Vector
Self-defined Self-defined
Point Vector
point.py vector.py
module module
Figure 1-2: Importing the Vector class from the vector.py
In Figure 12, we use the following Python command:
from vector import Vector
This command brings just the Vector class from vector.py. We’re not im
porting anything else defined in vector.py.
As you’ll see in the next section, there are a few ways to import from
modules.
Different Import Forms
To understand the different ways we can import modules and names inside
a module, let’s use two packages from our Mechanics project.
6 Chapter 1
Mechanics
|- geom2d
| |- __init__.py
| |- point.py
| |- vector.py
|
|- eqs
| |- __init__.py
| |- matrix.py
| |- vector.py
For this example, we’ll use the geom2d and eqs packages, using two files, or
modules, inside of each. Each of these modules defines a single class that
has the same name as the module, only capitalized. For example, the mod
ule in point.py defines the Point class, vector.py defines the Vector class, and
matrix.py defines the Matrix class. Figure 13 illustrates this package structure.
package
package geom2d
module point module vector
Point Vector
package
package eqs
module matrix module vector
Matrix Vector
Figure 1-3: Two packages from our Mechanics
project and some of their modules
With this directory set up in our minds, let’s analyze several scenarios.
Importing from a Module in the Same Package
If we are in module point.py from the package geom2d and we want to import
the entire vector.py module, we can use the following:
import vector
Now we can use the vector.py module’s contents like so:
v = vector.Vector(1, 2)
It’s important to note that since we imported the entire module and not
any of its individual entities, we have to refer to the moduledefined entities
using the module name. If we want to refer to the module using a different
name, we can alias it:
import vector as vec
A Short Python Primer 7