Monday 5 September 2011

How to share Python code with PyDev for Eclipse

Python allows sharing the code between projects. Shared code (classes, functions,...) is grouped by its purpose/nature into modules which are imported into projects. Modules are simple text files containing Python code and they have extension .py. Modules are organized into packages. Package is actually a directory which contains __init__.py file, modules and/or other packages.

Let us create package named common which contains one module, crypto.

File->New->Python Project

Project Name: common
Directory: C:\Users\Bojan\workspace\Python\common
Project type: Python
Grammar version: 2.7
Interpeter: Default
Create 'src' folder and add it to the PYTHONPATH

This creates following file hierarchy on the disk:

common
   - src (directory)
   - .project
   - .pydevproject

Packages/modules are usually added as subdirectories of src directory. If any other Python project wants to use any package from this project, it needs to add absolute path to common\src to its PYTHONPATH.

File->New->PyDev Package

This wizard forces us to pick src folder in some project as Source Folder:
Source Folder: /common/src
Name: util

File hierarchy on the disk now looks like this:

common
   - src (directory)
      - util (directory)
         - __init__.py
   - .project
   - .pydevproject

A new directory - util - has been created and file __init__.py has been automatically added to it. It is empty by default and we can leave it as such. This file marks its parent directory (util) as Python package directory

Let us add module crypto to util package:

File->New->PyDev Module:
Source Folder: /common/src (wizard allows only src directories form Python projects to be selected here)
Package: util (from /common/src)
Name: crypto
Template: empty

This adds crypto.py file to util directory. Hierarchy on the disk is now:

common
   - src (directory)
      - util (directory)
         - __init__.py
         - crypto.py
   - .project
   - .pydevproject

If path to common\src is added to PYTHONPATH in some Python project, any Python file belonging to it is able to import crypto module from util package by including this line:

from util import crypto
or
from util.crypto import *

PYTHONPATH is project specific and PyDev uses it to locate source files for compiling, running autocompletion and debugging.

Let's add some function to crypto.py:

import hashlib

def get_md5(file_path):
    md5 = hashlib.md5()
    with open(file_path,"rb") as f: 
        for chunk in iter(lambda: f.read(128 * md5.block_size), ''): 
            md5.update(chunk)
    return md5.hexdigest()

Let us create now a new Python project (named md5) which uses get_md5 function from util.crypto module: 
File->New->PyDev Project, Name: md5. We now need to add path to desired module to PYTHONPATH for this project: select project name in the Navigator pane; right-click, Properties; select PyDev - PYTHONPATH; select "External Libraries" tab (as we're adding source that does not belong to this workspace); click on "Add source folder" and browse to the common\src directory (e.g. "C:\Users\Bojan\workspace\Python\common\src"). 

main.py:
import sys
from util.crypto import get_md5

def main():
    print get_md5(r"c:\test\foo.exe")

if __name__ == "__main__":
    sys.exit(main())


Links and references:

How to organize a Python Project?
The Python Tutorial: Modules

No comments: