Learn Python Series (#9) - Using Import

in #utopian-io7 years ago (edited)

Learn Python Series (#9) - Using import

python_logo.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 (#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:

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:

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:

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:

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:

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:

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:

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:

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 ...

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:

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

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

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:

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:

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:

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:

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:

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:

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!



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

Thank you for the contribution. It has been approved.

You can contact us on Discord.
[utopian-moderator]

Thank you!

Great post.
I like it.. thanks for sharing this post

Great! And you're welcome! Many more episodes will follow in the Learn Python Series, so stay tuned and follow along! :-)

Very helpful post @scipio

Thanks for the compliment ;-)

Great and valuable blog @scipio thanks

Thank you, very kind. I wrote it with love !

python is a hard subject.
it's helpful to post.
go ahead

Excellent friend. Thank yo for you support.

Hey @scipio I am @utopian-io. I have just upvoted you!

Achievements

  • WOW WOW WOW People loved what you did here. GREAT JOB!
  • Seems like you contribute quite often. AMAZING!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

:) You are great. Sorry for this double comment. Was a bug with the bot.