Friday, June 1, 2012

Laying the Egg

Modules:

To understand about eggs lets start with modules first. Dont panic! A python module is simply a python file with python code. It is all the same as a python program but the only difference being the fact that programs are designed to run, whereas modules consist of code that is written with reusability in mind i.e. module are mainly designed to be imported and used by other programs.

#file echo.py

def sayIt(arg_str):
    print("you said: " + arg_str)
Enter Python interpreter and execute:

>>> from echo import sayIt
>>> sayIt ("I said something")    
Python files can also be run as a script such as

>>> python echo.py "I said something"
However to accomplish this we need to add

if __name__ == "__main__":
    import sys
    sayIt(sys.argv[1])
Thus the code can be run both as a script and imported as a module file. The code that parses the command line is executed only when the module is executed as the main file. Running the module 
as a script is usually very convenient.


When importing a module, the interpreter first tries to search in built-in modules. If not found, the search continues in directories defined by the variable sys.path which usually include:
  • The directory that contains the program (usually current directory)
  • PYTHONPATH env variable (if set)
  • Installation dependant defaults (set at install time)

Packages: 

Module files are organised into packages. A package is a collection of modules inside a directory containing __init__.py file. The __init__.py tells the python interpretor to treat the directory as a python package. 


For example myPackage could look something like:



MyPackage/
    __init__.py
    module1.py
    module2.py


Similarly MyPackage.subPackage would look like



MyPackage/
    __init__.py
    module1.py
    module2.py
    subPackage/
        __init__.py
        module3.py
        module4.py

Packages can be imported in many ways depending on what functionality is exactly required from the package.

We can either:
  • import package.module or import package.subpackage.module
    • usage: package.subpackage.module.method()
  • from package.subpackage import module
    • usage: module.method()
  • from package.subpackage.module import method
    • usage: method()

__init__.py:

In the simplest cases, __init__.py file can be an empty file. However, we can provide some code e.g. sometimes it is convenient to load all the modules inside a package (from MyPackage import * ) and thus we must specify all the included modules as:



__all__=['module1','module2', 'moduleN']



Since __init__.py is the first file to be loaded in a module it may contain initialisation code for the package.


It is best to place python packages in directories that are on sys.path. Thus they can be easily found and imported whenever required. 

Distribute

Now we prepare to distribute! 

We can either create an sdist (source distribution) using distutils.core or an egg (binary distribution) using setuptools. More on that later

Source Distribution:

In the simplest of cases, the distribution would contain a setup.py file and the package folder such as:

MyDistribution/
    setup.py
    README.txt (optional)
    mydistribution/
        module1.py
        module2.py
The setup.py file contains metadata about the project e.g.
from distutils.core import setup

setup(
    name='MyDistribution',
    version='0.1dev',
    packages=['mydistribution',],
    license='Creative Commons Attribution-Noncommercial-Share Alike license',
    long_description=open('README.txt').read(),
)
Now to create a release we need to run the command
>>> python setup.py sdist
This will create a dist sub-directory in the project directory containing the distribution as a compressed archive e.g. MyDistribution-0.1.tar.gz

Note that the distribution does not include all files in the directory :-) more on that later.
All the files included in the distribution are reflected in a MANIFEST file which is also create by sdist.

The distribution is now ready to be registered anywhere. 

Binary Distribution (Egg):

Python eggs are similar to jar files in java or rpms in linux.
To create a binary distribution, the setup.py file is changed to:
from setuptools import setup

setup(
    name='MyDistribution',
    version='0.1dev',
    packages=['mydistribution',],
    license='Creative Commons Attribution-Noncommercial-Share Alike license',
    long_description=open('README.txt').read(),
)
To create a release we need to run the command
>>> python setup.py bdist_egg

The dist subdirectory now contains the newly laid egg MyDistribution-0.1-py-x.x.egg (where x.x is the python version used to create the egg)

Next we register the egg :-)




No comments:

Post a Comment