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 import module
2 x = module.test.Klass()
3 print x.status()
4
module/_dev/test.py is similarly simple (the model and prod versions respectively return "model" and "prod" instead of "dev"):
1 class Klass(object):
2 def status(self):
3 return '%s in dev' % str(self)
module/__init__.py
:
1 import os
2
3 env = os.environ.get('ENV','dev').lower()
4
5 if env == 'prod':
6 from _prod import *
7 elif env == 'model':
8 from _model import *
9 else:
10 from _dev import *
__init__.py
in _dev
, _model
, and _prod
:
1 import os
2
3 def _load_code():
4 parent_dir = os.path.dirname(__file__)
5 base = os.path.basename(os.path.dirname(parent_dir))
6 modules = []
7 for root, dirs, files in os.walk(parent_dir):
8 for name in files:
9 if name.endswith('.py') and \
10 not name.startswith('__') and \
11 not name.startswith('.'):
12 module_name = '%s.%s.%s' % (base,
13 os.path.basename(parent_dir),
14 name.rsplit('.', 1)[0].replace(os.sep, '.'))
15 __import__(module_name)
16 modules.append(module_name)
17 return modules
18
19 __all__ = []
20
21 def update__all__():
22 global __all__
23 __all__ = [x.rsplit('.',1)[-1] for x in _load_code()]
24
25 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
This work is licensed under a Creative Commons Attribution 3.0 Unported License.
The thoughts expressed here are my own and do not necessarily represent those of my employer.