Learn Python Series (#9) - Using Import
Learn Python Series (#9) - Using import
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
- Learn Python Series (#2) - Handling Strings Part 1
- Learn Python Series (#3) - Handling Strings Part 2
- Learn Python Series (#4) - Round-Up #1
- Learn Python Series (#5) - Handling Lists Part 1
- Learn Python Series (#6) - Handling Lists Part 2
- Learn Python Series (#7) - Handling Dictionaries
- 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
, anint
or alist
or afor
andwhile
; - when you've written a function
def
or aclass
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
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
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
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.