modules part 2

A place where you can post Python-related tutorials you made yourself, or links to tutorials made by others.

modules part 2

Postby metulburr » Tue Jun 04, 2013 10:18 pm

Module Creation
Python modules are just files of python code. You do not need to write special syntax to tell python you are making a module. To create a module, write some python code into a file and save as .py extension (any file is already considered a module). All names assigned at the top level of the module become its attributes and are exported for the clients to use.

If you create a module (lets call it mod1.py) with the following syntax:
Code: Select all
def printer(var):
   print(var)

If you import mod1, you create a module with one attribute, the name printer.

module Usage
You can import this module one of 2 ways:

the import statement:
This method identifies an external file to be loaded. It creates mod1 as a variable in the script. mod1 references the module object after it is done being loaded. We must then use the module name to fetch its attributes.
Code: Select all
import mod1
mod1.printer('test')

the from statement:
The from statement copies the names from one file over to another scope. It allows us to use the copied namess directly in the script wihtout going through the module. However printer has less meaning to a reader than mod1.printer. Also it has the potential to silently overwrite names, if you imported names that that have the same names as existing variables in your scope. this peoblem does not occur in the import statement, as you always go through the module's name to get its contents.
Code: Select all
from mod1 import printer
printer('test')

the from * statement:
The previous applies here also, except this method copies all names in the module into the importing scope. It essentially collapses one namespace into another. Here is a tutorial on why this is NOT preferred.
Code: Select all
from mod1 import *
printer('test)


All of these are valid to import a module. The net effect of the from * statements though is less typing. However it is shunned upon as it floods the namespace. One example would be if you had a ton of modules to import and all of them used the from * statement. Where does printer() comes from, mod1? mod2? mod3? etc. etc.

Imports loaded once
AS state in part 1, modules are loaded and run of the first imoport or from, and only the first. Python does it once per file, once per process. As a result you could use it to initialze variables:
lets say we created a module mod2.py
Code: Select all
print('test')
var = 1

Code: Select all
>>> import mod2
test
>>> mod2.var
1
>>> mod2.var = 2
>>> import mod2
>>> mod2.var
2

mod2.var is still 2 as the second import just fetched the already loaded module. If however you wanted it to be reran, you could use imp.reload(). In python, you can access the attributes of any object that has attributes using the qualification syntax object.attribute.

import and from are assignemnts
As wtih def, import and from are executable statements, not compile-time declarations. They could be nested in if tests, in function defs, etc. They are not ran until Python reaches them while executing your program.
an example would be:
Code: Select all
import sys

if sys.platform[:3] == 'win':
   import msvcrt
   def getchar():
      ...
else:
   import termios
   def getchar():
      ...

this program imports msvcrt if the platform is windows, or else imports termios. Where msvcrt causes an import error on linux for example. With more code not shown, you could define getchar() one way if windows, or another way if linux, etc.

Module Namespaces
lets call this module mod3.py
Code: Select all
print('loading')
import sys

name = 20

def func():
   pass

class Klass:
   pass
print('done loading')

"name" is an attribute of mod3, which we refer to outside of the module as
Code: Select all
mod3.name

The "name" variable is also global variable to any other code inside mod3.py.
If you import this module the two print statements execute at import time:
Code: Select all
>>> import mod3
loading
done loading
>>>

Once done loading, it's scope becomes an attribute namespace in the module object we get back from import. We can access attributes in this namespace by qualifying them with the name of the enclosing module.
Code: Select all
>>> mod3.sys
<module 'sys' (built-in)>
>>> mod3.name
20
>>> mod3.func
<function func at 0x7fbbcda49d40>
>>> mod3.Klass
<class 'mod3.Klass'>
>>>


Internally, module namespaces are stored as dictionary objects, to view the object
Code: Select all
>>> list(mod3.__dict__.keys())
['__builtins__', '__file__', 'func', '__name__', 'Klass', '__package__', 'name', '__initializing__', '__cached__', '__loader__', 'sys', '__doc__']
>>>

Python adds some namespace for us, like:
__file__ is the name of the file the module was loaded from
__name__ gives its name as known to importers (without the .py ext and directory path)
Code: Select all
>>> mod3.__file__
'./mod3.py'
>>> mod3.__name__
'mod3'
>>>


reload
imp.reload forces an already loaded module's code to be reloaded and rerun.

lets make a module called mod4.py and in it:
Code: Select all
msg = 'first'

def printer():
   print(msg)


now go to the interpreter and import that module.
Code: Select all
>>> import mod4
>>> mod4.printer()
first
>>> mod4.msg
'first'
>>>

now keep the interpreter open (this signifies a program that is still running) and modify the module, to something like:
Code: Select all
msg = 'second'

def printer():
   print(msg)
   

and save and back to the interpreter:
Code: Select all
>>> mod4.printer()
first

printer() still returns the old data, so to get its current, we have to reload that module
Code: Select all
>>> from imp import reload
>>> reload(mod4)
<module 'mod4' from './mod4.py'>
>>> mod4.printer()
second


Go to Modules Part 3
Go to Modules Part 1
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1562
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Return to Tutorials

Who is online

Users browsing this forum: No registered users and 0 guests