Introduction

This is work in progress - will keep working on it over the next few days

Which import statement format and what folder/package structure should one use for an application.

In my project I had all source code in one folder, over time this became to be a hassle. I have recently started on a major revision of my software and wanted to take advantage of organizing it better.

I wanted to structure things into packages to make it easier to find things and this will hopefully also force/push me into better code reuse.

It was relatively easy to come up with a folder and package structure (at least the basic stuff to get going).

That pretty quickly brought out the problem on how to import things, my initial reading suggested to use relative imports, this looked great to start with but I soon run into trouble with sub-package/inter-package imports, so back to reading and asking for help on the wxPython list.

As always the wxPython list members (special thanks to Chris Barker, Robin Dunn and Oliver Schoenborn) where very very helpful even so this topic is really more a Python issue and nothing specific to wxPython.

The folder/package structure

The structure should allow a good organization of the source code and it should be possible to run individual modules in sub-packages, e.g. to test layouts of such things as a panel etc.

Below is a sub-set of what I am starting to use and it should be enough to explain the import issues I run into and the solutions to them.

dev
dev/aproject 
dev/aproject/setup_lib.py
dev/aproject/aprojsrc/
dev/aproject/aprojsrc/__init__.py
dev/aproject/aprojsrc/mypub.py
dev/aproject/aprojsrc/mypubtopics.py
dev/aproject/aprojsrc/libui
dev/aproject/aprojsrc//libui/__init__.py
dev/aproject/aprojsrc/libui/textctrl.py
dev/aproject/aprojsrc/model/__init__.py
dev/aproject/aprojsrc/model/m_masterdata.py

Obviously a real project would have some more folders for such things as documentation, scripts etc.

"aproject" is the top/root folder for this project, it then has the "aprojsrc" folder which contains the Python modules and packages (defined by having a __init__.py module in them).

As I mentioned above I tried first with relative imports but did not get very far, before I gave up and then went with absolute imports.

In the above case absolute imports means that all import statemtents start with "import aprojsrc." or "from aprojsrc." as "aprojsrc" is the top level package, unless your import is referencing a module within the package you are importing from, in which case you just use "import moduleinthispackage".

setup_lib usage

However the use of absolute imports will cause a problem if you try to run e.g. "libui/textctrl.py" directly as "aprojsrc" is not in the Python path and if textctrl.py contains e.g. "import aprojsrc.mypub it will fail.

The solution to this is to use the "develop" option of setuptools/distribute as shown below. After you create this setup_lib.py just run "python setup_lib.py develop" and it will create an egg in your site-packages folder and from then on you will be able to run textcrl.py in aprojsrc/libui as a standalone module and it will find "aprojsrc.pypub".

   1 # -*- coding: utf-8 -*-#
   2 #!/usr/bin/env python
   3 
   4 from setuptools import setup
   5 
   6 
   7 # This setup is suitable for "python setup.py develop".
   8 
   9 setup(
  10     name = "aprojsrc",
  11     version = "0.1.1",
  12     description='aprojsrc - just for running in development mode',
  13     author='whoeverdid this',
  14     author_email='who@wherever.com',
  15     packages = ["aprojsrc"],
  16     ) 

pubsub

When using wx.lib.pubsub version 3 api as included in wxPython 2.9.2.1 and using "pub.importTopicTree("aprojsrc.mypubtopics")" will fail as it doesn't handle the "." notation, a fix has been found and will be included in an upcoming release. Should you need the fix before check the topic "OT - at least a bit - application package/folder structure" on the pubsub list.

intra package import

My application uses SQLAlchemy and I based my stuff on how things are done in TurboGears 2.x, which means the "__init__.py" in the model package sets up some stuff which is then needed in e.g. m_masterdata.py. I should also state that I subscribe to the notion that "from something import *" is not to be used or only in very very rare occasions, instead I normally do e.g. "import sqlalchemy as sa" or "import sqlalchemy.orm as sao" and so on.

In m_masterdata.py I would therefore have liked to do "import aprojsrc.model as db" but that doesn't work as I am trying to import things from the __init__.py which is obviously within the package I am importing from, so I have to use "from appsource.model import *" or "from appsource.model import (DeclarativeBase, DBSession, andwhateverelse)".

If you select to use "from appsource.model import *" you might want to look into the __all__ variable, it limits what "*" will import and I believe it also helps speeding up the import.

Following some links which I found useful.

namespace - the Python definiton

packages - the Python definiton

packages - dive into python

importlib - Python 3 doc, also available in 2.7 on pypi

Comments

Please feel free to comment on the above you can use the wxPython list or send me an email to werner.bruhin at free.fr or just add it here.

Import and folder structure for appplication (last edited 2011-09-08 14:49:14 by 183)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.