importIntermediate
Learn Python Series):importUp 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"?
tuple, an int or a list or a for and while;def or a class or if you've declared a statement inside your current program file;import statement.The words package and module are oftentimes used as synonyms but they're not entirely the same.
__init__.py;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:
import your own Python modulesLet'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!
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!
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
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
asOftentimes 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
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
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).
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']
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.