February 28, 2009 at 12:32 pm
filed under programming
Tagged import, python, three tier
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
Justin
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…