Learn Python Series (#9) - Using Import

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@scipio·
0.000 HBD
Learn Python Series (#9) - Using Import
# Learn Python Series (#9) - Using `import`

![python_logo.png](https://res.cloudinary.com/hpiynhbhq/image/upload/v1521025447/pclw5zii7qkhuuj2z1ug.png)

#### What Will I Learn?
- You will learn what an import actually is, 
- what the difference is between a (sub)package and a (sub)module, 
- some various ways to import modules and module functionality, 
- how to alias modules and module attributes, 
- about how to get more information about a package, its modules and submodules.

#### Requirements
- A working modern computer running macOS, Windows or Ubuntu
- An installed Python 3(.6) distribution, such as (for example) the Anaconda Distribution
- The ambition to learn Python programming

#### Difficulty
Intermediate

#### Curriculum (of the `Learn Python Series`):
- [Learn Python Series - Intro](https://utopian.io/utopian-io/@scipio/learn-python-series-intro)
- [Learn Python Series (#2) - Handling Strings Part 1](https://utopian.io/utopian-io/@scipio/learn-python-series-2-handling-strings-part-1)
- [Learn Python Series (#3) - Handling Strings Part 2](https://utopian.io/utopian-io/@scipio/learn-python-series-3-handling-strings-part-2)
- [Learn Python Series (#4) - Round-Up #1](https://utopian.io/utopian-io/@scipio/learn-python-series-4-round-up-1)
- [Learn Python Series (#5) - Handling Lists Part 1](https://utopian.io/utopian-io/@scipio/learn-python-series-5-handling-lists-part-1)
- [Learn Python Series (#6) - Handling Lists Part 2](https://utopian.io/utopian-io/@scipio/learn-python-series-6-handling-lists-part-2)
- [Learn Python Series (#7) - Handling Dictionaries](https://utopian.io/utopian-io/@scipio/learn-python-series-7-handling-dictionaries)
- [Learn Python Series (#8) - Handling Tuples](https://utopian.io/utopian-io/@scipio/learn-python-series-8-handling-tuples)

# Learn Python Series (#9) - Using `import`

Up until here we have been discussing standard built-in Python data types, methods, functions and other mechanisms. And already we've covered quite a lot, which led to (for example in the Round-Up #1 episode) the creation of various useful self-developed functions.

However, only as of now, **the real Python Fun has just begun**! By using `import`.

In this episode you will learn what an `import` actually is, what the difference between a (sub)package and a (sub)module is, some various ways to import modules and module functionality, how to alias modules and module attributes, and how to get more information about a package, its modules and submodules.

# `import`?
Depending on which Python distribution you are using, for example Anaconda, some (or a lot of) **packages and modules** are already installed by default. They contain functionality, that becomes available to use in your own programs when you `import` it to your project. Once you have imported a package or module, you can use it in the current **project scope**. The functionality then gets **defined**.

When is certain Python functionality considered to be "defined" and therefore "usable"?

- in case the functionality is a part of your default Python distribution, for example a `tuple`, an `int` or a `list` or a `for` and `while`;
- when you've written a function `def` or a `class` or if you've declared a statement inside your current program file;
- when the functionality is inside another file (than the current one you are running) and that you have made it available inside your current file using an `import` statement.

# Packages versus modules
The words **package** and **module** are oftentimes used as synonyms but they're not entirely the same.

- a Python **package** is a directory with Python files in it and a "special file" named `__init__.py`;
- a **module** is a Python file that includes functions, classes, variable declarations. A module helps you to organize your code functionality, to put it in "blocks" that you can re-use when you need it, and only define it once (much like is the case with a function `def`).

Therefore a module contains the actual functionality, and is part of a package. A package is like a "container", and can contain multiple modules, and even other packages. So you can import entire packages, or individual modules, or functionality inside a module.

Also:

- in case you create a project directory that consists of multiple Python files, you could perceive your current project directory as a package and each Python file as a module;
- in case you want to make functionality in one of your files available to your other files, you need to import your own file as a module;
- you can import from other Python packages which are included in your Python distribution by default;
- and you can import Python packages developed by other, external, developers. Of course in this case, you first need to download & install such external packages before you're able to import them.

# `import` your own Python modules
Let's assume you have a current working directory called `my_project/` and in it is a file called `sup_funcs.py` (short for "support functions"). The contents of this file `sup_funcs.py`, which you wrote yourself, is the following code:


```python
def friendly_greeter(name):
    print("Hi {}, it's really good to see you again!".format(name))
```

Now let's also assume you've created another file named `main.py`, located inside `my_project/` as well. Suppose you want to use the `friendly_greeter()` function, located inside `sup_funcs.py`, and call it from within `main.py`. How do you do that?

Simply `import` the entire `sup_funcs.py` file inside `main.py`, like so:


```python
import sup_funcs
```

Just leave out the `.py` file extension. You have now **defined** and **made available** the contents of `sup_funcs.py` inside `main.py`. It's common practise to put all your `import` statements at the top of each Python file but that's not a necessity: the import statements could be anywhere.

Now to use the the `friendly_greeter()` function you need to call it by preceeding the module name in which the function is defined first, like so:


```python
sup_funcs.friendly_greeter('scipio')
```

    Hi scipio, it's really good to see you again!


# Using `from [module_name] import [object]`
In case you only want to import certain objects from a module, in this case only the function `friendly_greeter()` stored inside `sup_funcs.py`, you can use a `from [module_name] import [object]` statement. That way, you don't have to preceed the function name with the module it's contained in. For example:


```python
from sup_funcs import friendly_greeter
friendly_greeter('amosbastian')
```

    Hi amosbastian, it's really good to see you again!


**Nota bene:** it is allowed to use the `*` wildcard as an object name. In that case, you're directly importing everything contained in the imported module. While that might seem convenient - because you're importing all the needed module functionality in one go - the imported module might have the same object names as you declared inside your own Python program, which would cause bugs / unwanted and unforeseen program behavior. So even though you could use the `*` wildcard, it's better to avoid using it.

What you could do as an alternative is just use `import module_name`, and assign individual module functionality to local variables. For example:


```python
import sup_funcs
friendly_greeter = sup_funcs.friendly_greeter
friendly_greeter('freedom')
```

    Hi freedom, it's really good to see you again!


# Importing built-in modules
Python comes with a lot of built-in modules containing lots and lots of functionality you can freely use. Up until now, we haven't used any of them, not have I explained how to use them. We'll discuss the latter over the course of the forthcoming `Learn Python Series` episodes, but for now, let's just show you how to import a built-in module. For example let's import some functionality from the `math` module:


```python
import math
print(math.pi)
# 3.141592653589793
```

    3.141592653589793
    3.141592653589793


That `pi` approximation was not available to use prior to importing the `math` module, but now it is!

Again, if we want to use `pi` with preceeding the `math` module, we need to import it as follows:


```python
from math import pi
print(pi)
# 3.141592653589793
```

    3.141592653589793


# Import multiple (built-in) modules
You can import to your program as many modules, and / or individual objects from them, as you like. Either with multiple import statements, or by comma-separating multiple module names in one import statement.

For example:


```python
import math, random

for i in range(3):
    print(random.randint(1,10) * math.pi, end=' ')
    
# 31.41592653589793 15.707963267948966 18.84955592153876 
```

    31.41592653589793 15.707963267948966 18.84955592153876 

Or ...


```python
from math import pow
from random import randint

def squared(num):
    return int(pow(num, 2))

print(squared(randint(1,5)))
# 16 , if randint picked 4
```

    16


# Aliasing modules using `as`
Oftentimes it's convenient to use your own module and function names over the default ones (as in, how the imported module and the objects inside it are originally named). You can modify those default names, for example for brevity or in case you have already used a module (function) name, by **aliasing modules and/or module objects**. 

You can construct an import alias like so:

`import [module_name] as [something_else]`

Let's for example import alias the `math` module as `m` and use `pi` from there:


```python
import math as m
print(m.pi)
# 3.141592653589793
```

    3.141592653589793


Or, a nonsense example to alias an already short object name:


```python
from math import pi as the_number_pi
print(the_number_pi)
# 3.141592653589793
```

    3.141592653589793


# Importing external packages and modules


If you want to import an external Python module, before being able to import (and use) it, you could first check from  your Python interpreter (at the time I'm writing this, for me it's a Jupyter Notebook iPython interpreter) if the given module is ready to be used.

Inside your Python interpreter, just try to import the given module and check the interpreter's response. If you don't receive feedback from the interpreter, that (most probably) means you can freely call the module. But in case you do get an error message, your Python interpreter couldn't find nor use the module you are trying to import.

For example, on trying to import a bogus module:


```python
import bla
```


    ---------------------------------------------------------------------------

    ModuleNotFoundError                       Traceback (most recent call last)

    <ipython-input-37-e4221d4a77a3> in <module>()
    ----> 1 import bla
    

    ModuleNotFoundError: No module named 'bla'


Your Python 3.6 distribution almost certainly also allows you to install external modules and packages using `pip` from the command line. Let's say for example you want to install (using pip) the package `matplotlib` (which we'll discuss in forthcoming `Learn Python Series` episodes).

Then first, on the command line (so **not** inside your Python interpreter but in "the terminal") do this:

`pip install matplotlib`

And afterwards, once it is installed, you can import it inside your own program, exactly like we've discussed above regarding your own modules and using built-in Python modules:


```python
import matplotlib
```

# Exploring module objects using `dir()` and `__doc__`
Having all those module functionalities available to use is of course very interesting and might seem powerful as well, but how do you know (apart from just using everything I wrote in the `Learn Python Series` of course!) what exactly is available for you to use inside a module?

In general, the `dir()` function aims to return a list of the object's attributes; a sorted strings list including the names inside the module. If the object has a `__dir__()` method then `dir()` calls that method and returns its attribute list, and otherwise it tries to gather information using the `__dict__` attribute and object type, but then the returned list could be incomplete.

Using `dir()` to gather information about, for example, the `math` module, can be done like so:


```python
dir(math)
```




    ['__doc__',
     '__file__',
     '__loader__',
     '__name__',
     '__package__',
     '__spec__',
     'acos',
     'acosh',
     'asin',
     'asinh',
     'atan',
     'atan2',
     'atanh',
     'ceil',
     'copysign',
     'cos',
     'cosh',
     'degrees',
     'e',
     'erf',
     'erfc',
     'exp',
     'expm1',
     'fabs',
     'factorial',
     'floor',
     'fmod',
     'frexp',
     'fsum',
     'gamma',
     'gcd',
     'hypot',
     'inf',
     'isclose',
     'isfinite',
     'isinf',
     'isnan',
     'ldexp',
     'lgamma',
     'log',
     'log10',
     'log1p',
     'log2',
     'modf',
     'nan',
     'pi',
     'pow',
     'radians',
     'sin',
     'sinh',
     'sqrt',
     'tan',
     'tanh',
     'tau',
     'trunc']



In case you want to gather more information about a specific module attribute, it could be worth checking if any info is contained in the attribute's `docstring` (if available), via calling `__doc__`. For example:


```python
print(math.sin.__doc__)
```

    sin(x)
    
    Return the sine of x (measured in radians).


# Locating and importing package submodules
In case a (large) package, such as - for example - `matplotlib` contains **submodules**, then you need to explicitly import those submodules in order to use the functions that submodule defines. But how to locate those submodules?

Python provides a built-in module called `pkgutil` ("package utilities") that you can use (among other things) to list a package's submodules with.

To list all the `matplotlib` submodules for example, you can do this:


```python
import matplotlib
import pkgutil

package = matplotlib
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__):
    print("Submodule: {}, Package: {}".format(modname, ispkg))
```

    Submodule: _animation_data, Package: False
    Submodule: _cm, Package: False
    Submodule: _cm_listed, Package: False
    Submodule: _cntr, Package: False
    Submodule: _color_data, Package: False
    Submodule: _contour, Package: False
    Submodule: _image, Package: False
    Submodule: _mathtext_data, Package: False
    Submodule: _path, Package: False
    Submodule: _png, Package: False
    Submodule: _pylab_helpers, Package: False
    Submodule: _qhull, Package: False
    Submodule: _tri, Package: False
    Submodule: _version, Package: False
    Submodule: afm, Package: False
    Submodule: animation, Package: False
    Submodule: artist, Package: False
    Submodule: axes, Package: True
    Submodule: axis, Package: False
    Submodule: backend_bases, Package: False
    Submodule: backend_managers, Package: False
    Submodule: backend_tools, Package: False
    Submodule: backends, Package: True
    Submodule: bezier, Package: False
    Submodule: blocking_input, Package: False
    Submodule: category, Package: False
    Submodule: cbook, Package: True
    Submodule: cm, Package: False
    Submodule: collections, Package: False
    Submodule: colorbar, Package: False
    Submodule: colors, Package: False
    Submodule: compat, Package: True
    Submodule: container, Package: False
    Submodule: contour, Package: False
    Submodule: dates, Package: False
    Submodule: docstring, Package: False
    Submodule: dviread, Package: False
    Submodule: figure, Package: False
    Submodule: finance, Package: False
    Submodule: font_manager, Package: False
    Submodule: fontconfig_pattern, Package: False
    Submodule: ft2font, Package: False
    Submodule: gridspec, Package: False
    Submodule: hatch, Package: False
    Submodule: image, Package: False
    Submodule: legend, Package: False
    Submodule: legend_handler, Package: False
    Submodule: lines, Package: False
    Submodule: markers, Package: False
    Submodule: mathtext, Package: False
    Submodule: mlab, Package: False
    Submodule: offsetbox, Package: False
    Submodule: patches, Package: False
    Submodule: path, Package: False
    Submodule: patheffects, Package: False
    Submodule: projections, Package: True
    Submodule: pylab, Package: False
    Submodule: pyplot, Package: False
    Submodule: quiver, Package: False
    Submodule: rcsetup, Package: False
    Submodule: sankey, Package: False
    Submodule: scale, Package: False
    Submodule: sphinxext, Package: True
    Submodule: spines, Package: False
    Submodule: stackplot, Package: False
    Submodule: streamplot, Package: False
    Submodule: style, Package: True
    Submodule: table, Package: False
    Submodule: testing, Package: True
    Submodule: texmanager, Package: False
    Submodule: text, Package: False
    Submodule: textpath, Package: False
    Submodule: ticker, Package: False
    Submodule: tight_bbox, Package: False
    Submodule: tight_layout, Package: False
    Submodule: transforms, Package: False
    Submodule: tri, Package: True
    Submodule: ttconv, Package: False
    Submodule: type1font, Package: False
    Submodule: units, Package: False
    Submodule: widgets, Package: False


Next, you can import (for example) the submodule `widgets` as follows, and list all its attributes afterwards, like so:


```python
import matplotlib.widgets as widgets
dir(widgets)
```




    ['AxesWidget',
     'Button',
     'CheckButtons',
     'Circle',
     'Cursor',
     'Ellipse',
     'EllipseSelector',
     'Lasso',
     'LassoSelector',
     'Line2D',
     'LockDraw',
     'MultiCursor',
     'PolygonSelector',
     'RadioButtons',
     'Rectangle',
     'RectangleSelector',
     'Slider',
     'SpanSelector',
     'SubplotTool',
     'TextBox',
     'ToolHandles',
     'Widget',
     '_SelectorWidget',
     '__builtins__',
     '__cached__',
     '__doc__',
     '__file__',
     '__loader__',
     '__name__',
     '__package__',
     '__spec__',
     'absolute_import',
     'blended_transform_factory',
     'copy',
     'dist',
     'division',
     'np',
     'print_function',
     'rcParams',
     'six',
     'unicode_literals',
     'zip']



# What did we learn, hopefully?

That Python consists of "building blocks" that you can choose to import to your project in order to use its functionality and build upon. The Python Standard Library already includes a large amount of built-in functionality. A Python distribution such as Anaconda comes with many more pre-installed modules. Then there's a gigantic amount of externally installable modules. Concluding, the ready-to-use Python module "building blocks" ecosystem is **enormous**.

In the next `Learn Python Series` episodes we'll review several well-known Python modules, and I'll show you a few ways of how to use them. 

### Thank you for your time!


<br /><hr/><em>Posted on <a href="https://utopian.io/utopian-io/@scipio/learn-python-series-9-using-import">Utopian.io -  Rewarding Open Source Contributors</a></em><hr/>
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,