Python Concepts/Modules

From Wikiversity
Jump to navigation Jump to search


Objective[edit | edit source]

Books-aj.svg aj ashton 01f.png
  • 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 | edit source]

Lesson[edit | edit source]

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 | edit source]

Importing Module string[edit | edit source]

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 | edit source]

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 | edit source]

>>> 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 | edit source]

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 | edit source]

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 | edit source]

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'>],))
>>>

Assignments[edit | edit source]

Crystal Clear app kedit.svg

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

Further Reading or Review[edit | edit source]

Smiley green alien cry.svg Completion status: this resource is a stub, which means that pretty much nothing has been done yet.

References[edit | edit source]

1. Python's documentation:

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

2. Python's methods:


3. Python's built-in functions: