Three tier python imports

February 28, 2009 at 12:32 pm
filed under programming
Tagged , ,

Suppose you want to write a python module, and, like a good software developer, you want to keep a separation between your development, model/testing, and production versions of your code. This is a simple task with a few tricks in __init__.py.

First, our tester code:

1
2
3
import module
x = module.test.Klass()
print x.status()

module/_dev/test.py is similarly simple (the model and prod versions respectively return “model” and “prod” instead of “dev”):

1
2
3
class Klass(object):
    def status(self):
        return '%s in dev' % str(self)

module/__init__.py:

1
2
3
4
5
6
7
8
9
10
import os
 
env = os.environ.get('ENV','dev').lower()
 
if env == 'prod':
    from _prod import *
elif env == 'model':
    from _model import *
else:
    from _dev import *

__init__.py in _dev, _model, and _prod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import os
 
def _load_code():
    parent_dir = os.path.dirname(__file__)
    base = os.path.basename(os.path.dirname(parent_dir))
    modules = []
    for root, dirs, files in os.walk(parent_dir):
    for name in files:
        if name.endswith('.py') and \
          not name.startswith('__') and \
          not name.startswith('.'):
            module_name = '%s.%s.%s' % (base,
                        os.path.basename(parent_dir),
                        name.rsplit('.', 1)[0].replace(os.sep, '.'))
            __import__(module_name)
            modules.append(module_name)
    return modules
 
__all__ = []
 
def update__all__():
    global __all__
    __all__ = [x.rsplit('.',1)[-1] for x in _load_code()]
 
update__all__() # intial setup

When tester.py is run, it checks the environment variable ENV and imports the proper version of the file.

$ ENV=dev python ./tester.py
<module._dev.test.Klass object at 0x9d66e2c> in dev
$ ENV=model python ./tester.py
<module._model.test.Klass object at 0x9435e2c> in model
$ ENV=prod python ./tester.py
<module._prod.test.Klass object at 0x9f12e2c> in prod

Full source code.

1 comment

RSS / trackback

respond

  1. Justin

    on March 31, 2009 at 4:13 pm

    So, what do you think of the new U2 album? I don’t get most of this post, but I do get the U2 album…