Modules and stuff

Any Python program can be imported as a module.

A simple module:

# hello.py
print("Hello, world!")

Then you can tell your interpreter where to look for the module by executing the following (using the Windows directory):

>>> import sys
>>> sys.path.append('C:/python')

Now you can import your module:

>>> import hello
Hello, world!

Defining a function in a module

# hello2.py
def hello():
    print("Hello, world!")

Import:

>>> import hello2

The module is then executed, which means that the function hello is defined in the scope of the module, so you can access the function like this:

>>> hello2.hello()
Hello, world!

Adding Test Code in a Module

# hello3.py
def hello():
    print("Hello, world!")

# A test:
hello()

If you import it as a module, to use the hello function in another program, the test code is executed, as in the first hello module in this chapter.

>>> import hello3
Hello, world!
>>> hello3.hello()
Hello, world!

This is not what you want. The key to avoiding this behavior is checking whether the module is run as a program on its own or imported into another program. To do that, you need the variable name.

>>> __name__
'__main__'
>>> hello3.__name__
'hello3'

Correct version:

# hello4.py

def hello():
    print("Hello, world!")

def test():
    hello()

if __name__ == '__main__': test()

If you run this as a program, the hello function is executed; if you import it, it behaves like a normal module.

>>> import hello4
>>> hello4.hello()
Hello, world!

Make your module available

You have to put your modules to the right place:

>>> import sys, pprint
>>> pprint.pprint(sys.path)
['',
 '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
 '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
 '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload']

Place your hello script to one of the site-packages directory and try to import module again.

Telling the Interpreter Where to Look

Use environment variable PYTHONPATH.

export PYTHONPATH=$PYTHONPATH:∼/python

PACKAGES

To structure your modules, you can group them into packages. A package is basically just another type of module. The interesting thing about them is that they can contain other modules.

While a module is stored in a file (with the file name extension .py), a package is a directory. To make Python treat it as a package, it must contain a file named __init__.py.

Simple example:

File/Directory Description
∼/python/ Directory in PYTHONPATH
∼/python/drawing/ Package directory (drawing package)
∼/python/drawing/__init__.py Package code (drawing module)
∼/python/drawing/colors.py colors module
∼/python/drawing/shapes.py shapes module

Now we can do following:

import drawing             # (1) Imports the drawing package
import drawing.colors      # (2) Imports the colors module
from drawing import shapes # (3) Imports the shapes module

Using dir()

To find out what a module contains, you can use the dir function , which lists all the attributes of an object (and therefore all functions, classes, variables, and so on, of a module). If you print out dir(copy), you get a long list of names.

>>> import copy
>>> [n for n in dir(copy) if not n.startswith('_')]
['Error', 'PyStringMap', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']

Help and documentation

>>> help(copy.copy)
Help on function copy in module copy:

copy(x)
    Shallow copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.

This tells you that copy takes a single argument x and that it is a "shallow copy operation."

print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).

Source code

If you want to find source code of the script on filesystem, try following:

>>> print(copy.__file__)
/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/copy.py

The standard library

sys

The sys module gives you access to variables and functions that are closely linked to the Python interpreter.

Function/Variable Description
argv The command-line arguments, including the script name
exit([arg]) Exits the current program, optionally with a given return value or error message
modules A dictionary mapping module names to loaded modules
path A list of directory names where modules can be found
platform A platform identifier such as sunos5 or win32
stdin Standard input stream—a file-like object
stdout Standard output stream—a file-like object
stderr Standard error stream—a file-like object

os

Function/Variable Description
environ Mapping with environment variables
system(command) Executes an operating system command in a subshell
sep Separator used in paths
linesep Line separator ('\n', '\r', or '\r\n')
urandom(n) Returns n bytes of cryptographically strong random data
{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2018/tieto:modules-and-stuff:0",
      "title": "Modules, packages and others",
      "html": "\n          \n    \n\n    <h2>Modules and stuff</h2>\n<p>Any Python program can be imported as a module.</p>\n<p>A simple module:</p>\n<div class=\"highlight\"><pre><code># hello.py\nprint(&quot;Hello, world!&quot;)</code></pre></div><p>Then you can tell your interpreter where to look for the module by executing the following (using the Windows directory):</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import sys\n&gt;&gt;&gt; sys.path.append(&apos;C:/python&apos;)</code></pre></div><p>Now you can import your module:</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import hello\nHello, world!</code></pre></div><h3>Defining a function in a module</h3>\n<div class=\"highlight\"><pre><code># hello2.py\ndef hello():\n    print(&quot;Hello, world!&quot;)</code></pre></div><p>Import:</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import hello2</code></pre></div><p>The module is then executed, which means that the function hello is defined in the scope of the module, so you can access the function like this:</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; hello2.hello()\nHello, world!</code></pre></div><h3>Adding Test Code in a Module</h3>\n<div class=\"highlight\"><pre><code># hello3.py\ndef hello():\n    print(&quot;Hello, world!&quot;)\n\n# A test:\nhello()</code></pre></div><p>If you import it as a module, to use the hello function in another program, the test code is executed, as in the first hello module in this chapter.</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import hello3\nHello, world!\n&gt;&gt;&gt; hello3.hello()\nHello, world!</code></pre></div><p>This is not what you want. The key to avoiding this behavior is checking whether the module is run as a program on its own or imported into another program. To do that, you need the variable <strong>name</strong>.</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; __name__\n&apos;__main__&apos;\n&gt;&gt;&gt; hello3.__name__\n&apos;hello3&apos;</code></pre></div><p>Correct version:</p>\n<div class=\"highlight\"><pre><code># hello4.py\n\ndef hello():\n    print(&quot;Hello, world!&quot;)\n\ndef test():\n    hello()\n\nif __name__ == &apos;__main__&apos;: test()</code></pre></div><p>If you run this as a program, the hello function is executed; if you import it, it behaves like a normal module.</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import hello4\n&gt;&gt;&gt; hello4.hello()\nHello, world!</code></pre></div><h3>Make your module available</h3>\n<p>You have to put your modules to the right place:</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import sys, pprint\n&gt;&gt;&gt; pprint.pprint(sys.path)\n[&apos;&apos;,\n &apos;/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python37.zip&apos;,\n &apos;/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7&apos;,\n &apos;/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload&apos;]</code></pre></div><p>Place your hello script to one of the site-packages directory and try to import module again.</p>\n<h3>Telling the Interpreter Where to Look</h3>\n<p>Use environment variable PYTHONPATH.</p>\n<div class=\"highlight\"><pre><code>export PYTHONPATH=$PYTHONPATH:&#x223C;/python</code></pre></div><h2>PACKAGES</h2>\n<p>To structure your modules, you can group them into packages. A package is basically just another type of module. The interesting thing about them is that they can contain other modules.</p>\n<p>While a module is stored in a file (with the file name extension .py), a package is a directory. To make Python treat it as a package, it must contain a file named __init__.py.</p>\n<p>Simple example:</p>\n<table>\n<thead><tr>\n<th>File/Directory</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>&#x223C;/python/</td>\n<td>Directory in PYTHONPATH</td>\n</tr>\n<tr>\n<td>&#x223C;/python/drawing/</td>\n<td>Package directory (drawing package)</td>\n</tr>\n<tr>\n<td>&#x223C;/python/drawing/__init__.py</td>\n<td>Package code (drawing module)</td>\n</tr>\n<tr>\n<td>&#x223C;/python/drawing/colors.py</td>\n<td>colors module</td>\n</tr>\n<tr>\n<td>&#x223C;/python/drawing/shapes.py</td>\n<td>shapes module</td>\n</tr>\n</tbody>\n</table>\n<p>Now we can do following:</p>\n<div class=\"highlight\"><pre><code>import drawing             # (1) Imports the drawing package\nimport drawing.colors      # (2) Imports the colors module\nfrom drawing import shapes # (3) Imports the shapes module</code></pre></div><h3>Using dir()</h3>\n<p>To find out what a module contains, you can use the dir function , which lists all the attributes of an object (and therefore all functions, classes, variables, and so on, of a module). If you print out dir(copy), you get a long list of names.</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; import copy\n&gt;&gt;&gt; [n for n in dir(copy) if not n.startswith(&apos;_&apos;)]\n[&apos;Error&apos;, &apos;PyStringMap&apos;, &apos;copy&apos;, &apos;deepcopy&apos;, &apos;dispatch_table&apos;, &apos;error&apos;, &apos;name&apos;, &apos;t&apos;, &apos;weakref&apos;]</code></pre></div><h3>Help and documentation</h3>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; help(copy.copy)\nHelp on function copy in module copy:\n\ncopy(x)\n    Shallow copy operation on arbitrary Python objects.\n\n    See the module&apos;s __doc__ string for more info.</code></pre></div><p>This tells you that <strong>copy</strong> takes a single argument x and that it is a &quot;shallow copy operation.&quot;</p>\n<div class=\"highlight\"><pre><code>print(range.__doc__)\nrange(stop) -&gt; range object\nrange(start, stop[, step]) -&gt; range object\n\nReturn an object that produces a sequence of integers from start (inclusive)\nto stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.\nstart defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.\nThese are exactly the valid indices for a list of 4 elements.\nWhen step is given, it specifies the increment (or decrement).</code></pre></div><h3>Source code</h3>\n<p>If you want to find source code of the script on filesystem, try following:</p>\n<div class=\"highlight\"><pre><code>&gt;&gt;&gt; print(copy.__file__)\n/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/copy.py</code></pre></div><h2>The standard library</h2>\n<h3>sys</h3>\n<p>The sys module gives you access to variables and functions that are closely linked to the Python interpreter.</p>\n<table>\n<thead><tr>\n<th>Function/Variable</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>argv</td>\n<td>The command-line arguments, including the script name</td>\n</tr>\n<tr>\n<td>exit([arg])</td>\n<td>Exits the current program, optionally with a given return value or error message</td>\n</tr>\n<tr>\n<td>modules</td>\n<td>A dictionary mapping module names to loaded modules</td>\n</tr>\n<tr>\n<td>path</td>\n<td>A list of directory names where modules can be found</td>\n</tr>\n<tr>\n<td>platform</td>\n<td>A platform identifier such as sunos5 or win32</td>\n</tr>\n<tr>\n<td>stdin</td>\n<td>Standard input stream&#x2014;a file-like object</td>\n</tr>\n<tr>\n<td>stdout</td>\n<td>Standard output stream&#x2014;a file-like object</td>\n</tr>\n<tr>\n<td>stderr</td>\n<td>Standard error stream&#x2014;a file-like object</td>\n</tr>\n</tbody>\n</table>\n<h3>os</h3>\n<table>\n<thead><tr>\n<th>Function/Variable</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>environ</td>\n<td>Mapping with environment variables</td>\n</tr>\n<tr>\n<td>system(command)</td>\n<td>Executes an operating system command in a subshell</td>\n</tr>\n<tr>\n<td>sep</td>\n<td>Separator used in paths</td>\n</tr>\n<tr>\n<td>linesep</td>\n<td>Line separator (&apos;\\n&apos;, &apos;\\r&apos;, or &apos;\\r\\n&apos;)</td>\n</tr>\n<tr>\n<td>urandom(n)</td>\n<td>Returns n bytes of cryptographically strong random data</td>\n</tr>\n</tbody>\n</table>\n\n\n        "
    }
  }
}