Objective

edit
 
  • To become familiar with some of the more common modules.
  • To understand the syntax associated with modules.
  • To experiment with what you can do and what you can't do with modules.
  • To appreciate the extra power and flexibility which modules provide.

Page Index

edit

Lesson

edit

As powerful as Python is, it would be almost impossible to write meaningful code without importing certain modules.

Yes, handwritten code can sometimes replace information available in a module. For example, your code might contain the statement:

lower = 'abcdefghijklmnopqrstuvwxyz'

and your hand-written code is as good as:

lower = string.ascii_lowercase

In this situation you might decide that it's not necessary to import string.

But, what about a statement like:

error = sys.exc_info()

This statement provides essential information about the most recent error which execution of your code has caused. Only an expert could create hand-written code to replace this statement and an expert would not want to do so.

When so many powerful features are available in python's modules, it makes good sense to use them. With appropriate modules imported, your code reflects your good knowledge of python and your willingness to reap the benefits of the labor of others whose contribution to python makes our professional lives easier.

You're already familiar with some of python's modules: decimal, sys.

In this lesson we'll look first at module string and the basic syntax concerning the use of module string.

Module string

edit

Importing Module string

edit

The simplest way to use module string is to open python and import it.

$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import string
>>>

To see what you have imported:

>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'string': <module 'string' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py'>}
>>> string
<module 'string' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py'>
>>>

This shows that module string has been imported and it's available, but it doesn't tell us much about string.

For more information about module string:

>>> dir (string)
['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']
>>>
for v in dir(string) :
    print ('###########################')
    print ( v )
    print ( eval( 'string.'+v ),'\n' )
###########################
Formatter
<class 'string.Formatter'>

###########################
Template
<class 'string.Template'>

###########################
_ChainMap
<class 'collections.ChainMap'>

###########################
_TemplateMetaclass
<class 'string._TemplateMetaclass'>

###########################
__all__
['ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace', 'Formatter', 'Template']

###########################
__builtins__

**** Lengthy list of builtins. ****

###########################
__cached__
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/__pycache__/string.cpython-36.pyc

###########################
__doc__
A collection of string constants.

Public module variables:

whitespace -- a string containing all ASCII whitespace
ascii_lowercase -- a string containing all ASCII lowercase letters
ascii_uppercase -- a string containing all ASCII uppercase letters
ascii_letters -- a string containing all ASCII letters
digits -- a string containing all ASCII decimal digits
hexdigits -- a string containing all ASCII hexadecimal digits
octdigits -- a string containing all ASCII octal digits
punctuation -- a string containing all ASCII punctuation characters
printable -- a string containing all ASCII characters considered printable



###########################
__file__
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py

###########################
__loader__
<_frozen_importlib_external.SourceFileLoader object at 0x10209ff98>

###########################
__name__
string

###########################
__package__


###########################
__spec__
ModuleSpec(name='string', loader=<_frozen_importlib_external.SourceFileLoader object at 0x10209ff98>, origin='/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py')

###########################
_re
<module 're' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/re.py'>

###########################
_string
<module '_string' (built-in)>

###########################
ascii_letters
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

###########################
ascii_lowercase
abcdefghijklmnopqrstuvwxyz

###########################
ascii_uppercase
ABCDEFGHIJKLMNOPQRSTUVWXYZ

###########################
capwords
<function capwords at 0x1020a02f0>

###########################
digits
0123456789

###########################
hexdigits
0123456789abcdefABCDEF

###########################
octdigits
01234567

###########################
printable
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
^M^K^L

###########################
punctuation
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

###########################
whitespace

^M^K^L

Now that you know what's in module string, you can access the contents of string by name:

>>> string.__file__
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py'
>>> string.__spec__
ModuleSpec(name='string', loader=<_frozen_importlib_external.SourceFileLoader object at 0x1018accc0>, origin='/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/string.py')
>>> string.digits
'0123456789'
>>>


Importing Contents of Module string

edit

For more information about the contents of string, change syntax slightly and try again:

$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from string import *
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'ascii_letters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ascii_lowercase': 'abcdefghijklmnopqrstuvwxyz', 'ascii_uppercase': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'capwords': <function capwords at 0x100786ae8>, 'digits': '0123456789', 'hexdigits': '0123456789abcdefABCDEF', 'octdigits': '01234567', 'printable': '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c', 'punctuation': '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', 'whitespace': ' \t\n\r\x0b\x0c', 'Formatter': <class 'string.Formatter'>, 'Template': <class 'string.Template'>}
>>>

With a little formatting we see:

'ascii_letters':   'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 
'ascii_lowercase': 'abcdefghijklmnopqrstuvwxyz', 
'ascii_uppercase': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
'capwords':        <function capwords at 0x100786ae8>, 
'digits':          '0123456789', 
'hexdigits':       '0123456789abcdefABCDEF', 
'octdigits':       '01234567', 
'printable':       '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c', 
'punctuation':     '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', 
'whitespace':      ' \t\n\r\x0b\x0c', 
'Formatter':       <class 'string.Formatter'>, 
'Template':        <class 'string.Template'>}

The values in the left hand column above are keys of dictionary globals() and they are always strings. In the right hand column are the values associated with the keys of the left hand. As you can see, the values may or may not be strings.

Because globals() is a dictionary, it may be accessed like a dictionary:

>>> [ v for v in globals() if '__' not in v ]
['ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace', 'Formatter', 'Template']
# These values are the same as string.__all__ .
>>> globals()['digits']
'0123456789'
>>> globals()['ascii_uppercase']
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>>

The one name not seen in globals() is string.

>>> string
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'string' is not defined
>>> 
>>> 'string' in globals()
False
>>>

The contents of string are now available:

>>> ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> whitespace
' \t\n\r\x0b\x0c'
>>> whitespace == ' \t\n\r\v\f'
True
>>>

Experiment with the contents of string:

>>> capwords('the authOrizEd biogRAPHY of tHomas jeFferSON')
'The Authorized Biography Of Thomas Jefferson'
>>>
>>> printable == digits + ascii_lowercase + ascii_uppercase + punctuation + whitespace
True
>>> 
>>> dir(string._re)
['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'RegexFlag', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_alphanum_bytes', '_alphanum_str', '_cache', '_compile', '_compile_repl', '_expand', '_locale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'enum', 'error', 'escape', 'findall', 'finditer', 'fullmatch', 'functools', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'template']
>>> import re
>>> 
>>> dir(re)
['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'RegexFlag', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_alphanum_bytes', '_alphanum_str', '_cache', '_compile', '_compile_repl', '_expand', '_locale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'enum', 'error', 'escape', 'findall', 'finditer', 'fullmatch', 'functools', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'template']
>>> 
>>> re == string._re
True
>>>

Note:

While the statement import * is convenient, Python's Documentation states:

In most cases Python programmers do not use this facility since it introduces an unknown set of names into the interpreter, possibly hiding some things you have already defined.

.... in general the practice of importing * from a module or package is frowned upon, since it often causes poorly readable code. However, it is okay to use it to save typing in interactive sessions.

Changing and restoring contents of module string

edit
>>> whitespace = 'Hello, world!' ; whitespace
'Hello, world!'
>>> 
>>> whitespace = ' \t\n\r\x0b\x0c' ; whitespace
' \t\n\r\x0b\x0c'
>>> 
>>> whitespace = 'Hello, world!' ; whitespace
'Hello, world!'
>>> 
>>> from string import whitespace ; whitespace
' \t\n\r\x0b\x0c'
>>>

Using module string

edit

After you become familiar with the contents of module string, you may decide to import only the module and use the syntax that requires the name of the module:

$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import string
>>> 
>>> whitespace
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'whitespace' is not defined
>>> string.whitespace
' \t\n\r\x0b\x0c'
>>> 
>>> punctuation
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'punctuation' is not defined
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>>

You can change the contents of module string, but this not recommended. In extreme cases, you may have to quit() python and start again.

Creating your own module

edit

In this case we will be working with module decimal. If this module is new to you, spend some time looking at module decimal as if it were module string above.

In the present working directory create a Python source file, for example, myDec.py . This will become module myDec.

# file myDec.py

import decimal

# Handy abbreviations: 

D = decimal.Decimal

getC = decimal.getcontext()

T = decimal.DecimalTuple

# User-written function:

def doit(v1) :
    return D(v1) + D(5)

Invoke Python in interactive mode:

$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> from myDec import *
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 

'decimal': <module 'decimal' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/decimal.py'>, 

'D': <class 'decimal.Decimal'>, 

'getC': Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]), 

'T': <class 'decimal.DecimalTuple'>, 

'doit': <function doit at 0x1018a1950>}
>>> 
>>> decimal # Loaded from module myDec.
<module 'decimal' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/decimal.py'>
>>> 
>>> dir (decimal)
['BasicContext', 'Clamped', 'Context', 'ConversionSyntax', 'Decimal', 'DecimalException', 'DecimalTuple', 'DefaultContext', 'DivisionByZero', 'DivisionImpossible', 'DivisionUndefined', 'ExtendedContext', 'FloatOperation', 'HAVE_THREADS', 'Inexact', 'InvalidContext', 'InvalidOperation', 'MAX_EMAX', 'MAX_PREC', 'MIN_EMIN', 'MIN_ETINY', 'Overflow', 'ROUND_05UP', 'ROUND_CEILING', 'ROUND_DOWN', 'ROUND_FLOOR', 'ROUND_HALF_DOWN', 'ROUND_HALF_EVEN', 'ROUND_HALF_UP', 'ROUND_UP', 'Rounded', 'Subnormal', 'Underflow', '__builtins__', '__cached__', '__doc__', '__file__', '__libmpdec_version__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'getcontext', 'localcontext', 'setcontext']
>>> 
>>> The various contexts:
>>> 
>>> type(decimal.BasicContext)
<class 'decimal.Context'>
>>> 
>>> type(decimal.DefaultContext)
<class 'decimal.Context'>
>>> 
>>> type(decimal.ExtendedContext)
<class 'decimal.Context'>
>>> 
>>> type(decimal.getcontext)
<class 'builtin_function_or_method'>
>>> type(decimal.getcontext())
<class 'decimal.Context'>
>>> 
>>> T
<class 'decimal.DecimalTuple'>
>>> D
<class 'decimal.Decimal'>
>>> doit
<function doit at 0x1018a1950>
>>> 
>>> getC
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
>>> 
>>> doit(7)
Decimal('12')
>>> 
>>> getC.prec=31
>>> getC
Context(prec=31, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) # prec was changed to 31.
>>> 
>>> getC.prec=28
>>> D(1234567890123456789012345678901234567890)+0
Decimal('1.234567890123456789012345679E+39') # Precision of 28.
>>> 
>>> getC.prec=10
>>> D(1234567890123456789012345678901234567890)+0
Decimal('1.234567890E+39') # precision of 10
>>> 
>>> getC
Context(prec=10, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow]) # Precision of 10.
>>> 
>>> T(1,(3,4,5,6),-3)
DecimalTuple(sign=1, digits=(3, 4, 5, 6), exponent=-3)
>>> T(1,(3,4,5,6),-3).sign
1
>>> T(1,(3,4,5,6),-3).digits
(3, 4, 5, 6)
>>> T(1,(3,4,5,6),-3).exponent
-3
>>> 
>>> D(T(1,(3,4,5,6),-3))
Decimal('-3.456')

Slightly more advanced

edit

Let your file myDec.py be:

import decimal
# If module decimal was previously loaded, this statement is ignored.
# If module decimal was not previously loaded, this statement is executed.
# Same for 'import sys' below.

import sys

# Handy abbreviations:

getC = decimal.getcontext()

T = decimal.DecimalTuple

# User-written function:

def D (v1) :
    '''
This function converts value v1 to decimal object.
If there is an error in conversion, this function
attempts to avoid introducing another error in the
'except' clause by ensuring that module 'sys' is
available. It was loaded above.
'''
    if isinstance (v1, decimal.Decimal) : return v1

    error = output = ''
    try : output = decimal.Decimal(str(v1))
    except : error = sys.exc_info()[:2]

    if error :
        print ('myDec.D: error converting', str(v1)[:80], 'to Decimal:')
        print ('   ', error)
        return None

    return output

Invoke Python in interactive mode:

$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> from myDec import *
>>> 
>>> dir()
['D', 'T', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'decimal', 'getC', 'sys']
>>> 
>>> sorted(dir()) == sorted([ v for v in globals() ])
True
>>> v1 = Decimal(6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Decimal' is not defined
>>> decimal.Decimal(6)
Decimal('6')
>>> 
>>> D(6)
Decimal('6')
>>> type(D(6))
<class 'decimal.Decimal'>
>>> D(1.23)
Decimal('1.23')
>>> decimal.Decimal(1.23)
>>> Decimal('1.229999999999999982236431605997495353221893310546875')
>>> 
>>> D(4.).as_tuple()
DecimalTuple(sign=0, digits=(4, 0), exponent=-1)
>>> D(4.).as_tuple().digits
(4, 0)
>>> 
>>> D(49.).sqrt()
Decimal('7.0')
>>> 
>>> D(3+4j)
myDec.D: error converting (3+4j) to Decimal:
    (<class 'decimal.InvalidOperation'>, InvalidOperation([<class 'decimal.ConversionSyntax'>],))
>>>

globals() unique to each module

edit

This example (on UNIX) shows how to access global variables across modules.

Create 2 files test1.py and test.py.

# test1.py
def test1_ReceiveGlobals(dict1) :
    for v in dict1 :
        globals()[v] = dict1[v]

def test1_SendGlobals() :
    return globals()

# test.py
from test1 import *

def set_globals() :
    t1 = (
    ('test1_23',67),
    ('test1_24',83),
    ('common_1',17), # This name is repeated below against "global".
    ('common_2',23), # This name is repeated below against "global".
    )
    dict1 = dict(  t1  )
    test1_ReceiveGlobals(dict1)
    global test_46,test_47
    global common_1,common_2                   # These 2 names exist in "dict1" above.
    test_46 = 79
    test_47 = 41
    common_1 = 'φιλοσοφοῦμεν ἄνευ μαλακίας.'   # This name exists in "dict1" above.
    common_2 = 'These are the times that ....' # This name exists in "dict1" above.


def print_globals() :
    print ()
    print ('globals():')
    for v in [v for v in globals() if '__' not in v]:
        print ('globals[{}] = {}'.format(v, globals()[v]))

    test1_globals = test1_SendGlobals()
    print ()
    print ('test1_globals:')
    for v in [v for v in test1_globals if '__' not in v]:
        print ('test1_globals[{}] = {}'.format(v, test1_globals[v]))


print_globals()
set_globals()
print_globals()

Invoke test.py:

$ python3.6  ./test.py  >sout  2>serr ; echo $? ; wc sout serr
0
      28     107    1224 sout
       0       0       0 serr
      28     107    1224 total
# file sout

globals():
globals[test1_ReceiveGlobals] = <function test1_ReceiveGlobals at 0x1022451e0> # Common to both.
globals[test1_SendGlobals] = <function test1_SendGlobals at 0x102245268>       # Common to both.
globals[set_globals] = <function set_globals at 0x100561e18>     # Unique to test.
globals[print_globals] = <function print_globals at 0x1022452f0> # Unique to test.

test1_globals:
test1_globals[test1_ReceiveGlobals] = <function test1_ReceiveGlobals at 0x1022451e0> # Common to both.
test1_globals[test1_SendGlobals] = <function test1_SendGlobals at 0x102245268>       # Common to both.

globals():
globals[test1_ReceiveGlobals] = <function test1_ReceiveGlobals at 0x1022451e0> # Common to both.
globals[test1_SendGlobals] = <function test1_SendGlobals at 0x102245268>       # Common to both.
globals[set_globals] = <function set_globals at 0x100561e18>     # Unique to test.
globals[print_globals] = <function print_globals at 0x1022452f0> # Unique to test.
globals[test_46] = 79                                            # Unique to test.
globals[test_47] = 41                                            # Unique to test.
globals[common_1] = φιλοσοφοῦμεν ἄνευ μαλακίας.   # Name exists in test1 below. Value is different.
globals[common_2] = These are the times that .... # Name exists in test1 below. Value is different.

test1_globals:
test1_globals[test1_ReceiveGlobals] = <function test1_ReceiveGlobals at 0x1022451e0> # Common to both.
test1_globals[test1_SendGlobals] = <function test1_SendGlobals at 0x102245268>       # Common to both.
test1_globals[test1_23] = 67 # Unique to test1.
test1_globals[test1_24] = 83 # Unique to test1.
test1_globals[common_1] = 17 # Name exists in test above. Value is different.
test1_globals[common_2] = 23 # Name exists in test above. Value is different.

Imported module invokes function in main module

edit

File test5.py:

def test5_doit() :
    main5_doit()

File main5.py:

import test5

def main5_doit() :
    print ('in main5_doit()')

test5.test5_doit()

Invoke main5.py:

$ python3.6  ./main5.py 
Traceback (most recent call last):
  File "./main5.py", line 6, in <module>
    test5.test5_doit()
  File "...../test5.py", line 2, in test5_doit
    main5_doit()
NameError: name 'main5_doit' is not defined
$ 

Add one line of code to file main5.py:

import test5

def main5_doit() :
    print ('in main5_doit()')

test5.main5_doit = main5_doit
test5.test5_doit()

Invoke main5.py:

$ python3.6  ./main5.py 
in main5_doit()
$ 

Function main5_doit() in main module was invoked by code in imported module test5.

Assignments

edit
 

In the output of dir(string) are two names 'Formatter' and 'Template'. Because this page is about modules generally, and module string is used as an example, there has been no information presented concerning these two classes. For more information about these classes, see "Custom String Formatting" and "Template strings."


Experiment with statements such as import decimal, from decimal import *, import myDec, from myDec import *.


Become familiar with the syntax associated with contents of modules, such as: Decimal(6), decimal.Decimal(6), myDec.decimal.Decimal(6), D(6), myDec.D(6).


Experiment with files main.py, test1.py, test2.py, test3.py. In main.py include statements import test1, import test2, import test3. Implement functionality so that code in test1 can invoke functions in test2 and test3, and vice-versa.

Further Reading or Review

edit
  Completion status: this resource is a stub, which means that pretty much nothing has been done yet.

References

edit

1. Python's documentation:

"6. Modules", "string — Common string operations", "decimal — Decimal fixed point and floating point arithmetic", "7.11. The import statement"


2. Python's methods:


3. Python's built-in functions:

"globals()", "dir( [object] )", "eval(expression[, globals[, locals]])"