Python Data Persistence – User Defined Modules

Python Data Persistence – User Defined Modules

A module is a collection of Python objects such as functions, classes, and so on. Python interpreter is bundled with a standard library consisting of a large number of built-in modules, some of which we got acquainted with. Just as built-in modules, you can create a collection of your own functions and import them in an interactive Python session or in another script.

Any Python script (having .py extension) can be used as a module. The idea behind a user-defined module is the same as that of a built-in module. If the entire programming solution involves quite a large number of functions and classes, in that case putting all definitions in a single script is likely to be troublesome. A better way is to organize them in separate modules. Functions and classes of similar relevance are kept in one module. Such an approach makes the code easier to maintain. First of all, let us put some functions in a script called ‘mymodule.py

Example

‘docstring of mymodule’
def isprime(num):
x=2
for x in range(2,num):
if num%x==0:
return False
else:
return True
def iseven(num):
if num%2==0:
return True
else:
return False
def isleap(num):
if num%4==0:
return True
else:
return False

We can now import any function from this module in an interactive interpreter session, just as we imported the math module.

Example

>>> import mymodule
>>> mymodule . isprime ( 43 )
True
>>> mymodule . isprime ( 72 )
False
>>> mymodule . iseven ( 28 )
True
>>> mymodule . iseven ( 93 )
False
>>> mymodule . isleap (2019)
False
>>> mymodule . isleap ( 1996 )
True
>>>

It is also possible to import this module in another Python script. Here is an example script ‘moduledemo.py’

Example

#moduledemo.py
import mymodule
print (‘calling isprime function from mymodule1)
n=int(input(‘enter a number..’))
retval=mymodule.isprime(n)
if retval==True:
print ( ‘ { } is a prime number ‘ . format ( n ) )
else:
print ( ‘ { } is not a prime number ‘ . format ( n ) )

Output

E:\python37>python moduledemo.py
calling isprime function from mymodule
enter a number . . 39
39 is not a prime number
E:\python37>python moduledemo.py
calling isprime function from mymodule
enter a number . . 97
97 is a prime number

_name_ attribute
As is often said, everything in Python is an object. Likewise, a module – whether built-in or user-defined – is also an object of module class.

Example

>>> #module object – built-in module
. . .
>>> import math
>>> type(math)
<class ‘module’>
>>> #module object – user defined module
. . .
>>> import mymodule
>>> type(mymodule)
<class ‘module’>

Module object is characterized by various attributes. One of the important attributes of a module object is__name___and it has a peculiar behavior. Inside Python’s interactive shell, the__name__attribute returns ‘__main__’. It is the name of the top-level namespace in which the Python interpreter is running. However, the value of an imported module’s__name__ attribute is the name of the module itself (excluding the .py part from the script’s name)

Example

>>> #__name__ attribute of interactive shell
. . .
>>>__name__
‘__main__’
>>> #__name__ attrbute of imported module
. . .
>>> import math
>>> math.__name__
‘ math’
>>> import mymodule
>>> ‘mymodule.__name__
‘mymodule’

This is also the same in the case of a Python script. When a certain script is run from the command line, Python is running in scripting mode. Hence value of__name__in the script is ‘__main__’. So also,__name__attribute of a module imported in the script is its name itself. Run the following code from the command line.

Example

#moduledemo-1.py
import mymodule
print (‘_name_ of top level module: ‘ ,__name__)
print (‘__name__ of imported mymodule : ‘ , mymodule.__name__)

Output

E:\python37>python moduledemo-1.py
__name__of top level module:__main__
__name__ of imported mymodule: mymodule

A script having function definitions may also have certain executable code also in it. What happens if it is imported into another script? Let us see. Open mymodule.py and add statements that call is even( ) function after definitions.

Example

‘docstring of mymodule’
def isprime(num):
x=2
for x in range(2,num):
if num%x==0:
return False
else:
return True
def iseven(num):
if num%2==0:
return True
else:
return False
def isleap(num):
if num%4==0:
return True
else:
return False
##add following statements
n=int(input(‘enter a number..’))
retval=iseven(n)
if retval==True:
print ( ‘ { } is even ‘ . format ( n ) )
else:
print ( ‘ { } is odd ‘ . format ( n ) )

Now if the moduledemo.py is run (it imports my module in it). Look at the result, (figure 3.15)

E:\python37>python moduledemo.py
enter a number..23
23 is odd
calling is prime function from my module
enter a number23
23 is a prime number

You find that the executable part in the imported module also runs. Obviously, we don’t want this to happen. We do want the executable code to run when the module script is invoked but not when it is imported. The peculiar behavior of__name__attribute comes in handy here. As we saw, its value happens to be ‘__main__’ when a module script is run, but__name__attribute takes up its name when imported. So we have to test this attribute and run the executable code only if it is ‘__main__’. Modify the my module code as follows:

Example

‘docstring of mymodule’
def isprime(num):
x=2
for x in range(2,num):
if num%x==0:
return False
else:
return True
def iseven(num):
if num%2==0:
return True
else:
return False
def isleap(num):
if num%4==0:
return True
else:
return False
#modify as follows:
if __name__==’__main__’ :
n=int ( input ( ‘ enter a number . . ‘ ) )
retval=iseven(n)
if retval==True:
print ( ‘ { } is even ‘ . format ( n ) )
else:
print ( ‘ { } is odd ‘ . format ( n ) )

You can run mymodule.py independently but wouldn’t affect the execution of moduledemo.py. (figure 3.16)

E:\python37>python moduledemo.py
calling is a prime function from my module
enter a number..11
11 is a prime number