2

I've created python modules but they are in different directories.

/xml/xmlcreator.py
/tasklist/tasks.py

Here, tasks.py is trying to import xmlcreator but both are in different paths. One way to do it is include xmlcreator.py in the Pythonpath. But, considering that I'll be publishing the code, this doesn't seem the right way to go about it as suggested here. Thus, how do I include xmlcreator or rather any module that might be written by me which would be in various directories and sub directories?

Community
  • 1
  • 1
Hick
  • 35,524
  • 46
  • 151
  • 243

3 Answers3

2

Are you going to publish both modules separately or together in one package?

If the former, then you'll probably want to have your users install your xml module (I'd call it something else :) so that it is, by default, already on Python's path, and declare it as a dependency of the tasklist module.

If both are distributed as a bundle, then relative imports seem to be the best option, since you can control where the paths are relative to each other.

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
plasma
  • 848
  • 5
  • 9
  • Yep, just give the library a proper name that doesn't clash with anything already existing :) – Niklas B. May 14 '12 at 21:00
  • Agreed. And as a corollary, if you'll be sharing that module among various applications, then I'd definitely suggest my first suggestion. – plasma May 14 '12 at 21:02
  • Er, right. :) I guess I meant that it would be a good idea to distribute the modules separately if, say, the xml module will be used by othe modules. – plasma May 14 '12 at 21:03
2

The best way is to create subpackages in a single top-level package that you define. You then ship these together in one package. If you are using setuptools/Distribute and you want to distribute them separately then you may also define a "namspace package" that the packages will be installed in. You don't need to use any ugly sys.path hacks.

Make a directory tree like this:

mypackage/__init__.py
mypackage/xml/__init__.py
mypackage/xml/xmlcreator.py
mypackage/tasklist/__init__.py
mypackage/tasklist/tasks.py

The __init__.py files may be empty. They define the directory to be a package that Python will search in.

Except if you want to use namespace packages the mypackage/__init__.py should contains:

__import__('pkg_resources').declare_namespace(__name__)

And your setup.py file contain:

...
namespace_packages=["mypackage"],
...

Then in your code:

from mypackage.xml import xmlcreator
from mypackage.tasklist import tasks

Will get them anywhere you need them. You only need to make one name globally unique in this case, the mypackage name.

For developing the code you can put the package in "develop mode", by doing

python setup.py develop --user

This will set up the local python environment to look for your package in your workspace.

Keith
  • 42,110
  • 11
  • 57
  • 76
0

When I start a new Python project, I immediately write its setup.py and declare my Python modules/packages, so that then I just do:

python setup.py develop

and everything gets magically added to my PYTHONPATH. If you do it from a virtualenv it's even better, since you don't need to install it system-wide.

Here's more about it:

http://packages.python.org/distribute/setuptools.html#development-mode

ubik
  • 4,440
  • 2
  • 23
  • 29