<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>some thoughts &#187; three tier</title>
	<atom:link href="http://programmerthoughts.com/tags/three-tier/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmerthoughts.com</link>
	<description></description>
	<lastBuildDate>Fri, 10 Sep 2010 17:51:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Three tier python imports</title>
		<link>http://programmerthoughts.com/programming/three-tier-python-imports/</link>
		<comments>http://programmerthoughts.com/programming/three-tier-python-imports/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 18:32:16 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[three tier]]></category>

		<guid isPermaLink="false">http://johnandkaren.com/blog/?p=168</guid>
		<description><![CDATA[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&#40;&#41; print x.status&#40;&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>First, our tester code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> module
x = module.<span style="color: #dc143c;">test</span>.<span style="color: black;">Klass</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> x.<span style="color: black;">status</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>module/_dev/test.py is similarly simple (the model and prod versions respectively return &#8220;model&#8221; and &#8220;prod&#8221; instead of &#8220;dev&#8221;):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Klass<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> status<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'%s in dev'</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>module/__init__.py:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
env = <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ENV'</span>,<span style="color: #483d8b;">'dev'</span><span style="color: black;">&#41;</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> env == <span style="color: #483d8b;">'prod'</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> _prod <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">elif</span> env == <span style="color: #483d8b;">'model'</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> _model <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> _dev <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span></pre></td></tr></table></div>

<p>__init__.py in _dev, _model, and _prod:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> _load_code<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    parent_dir = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span>
    base = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">basename</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>parent_dir<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    modules = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> root, dirs, files <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">walk</span><span style="color: black;">&#40;</span>parent_dir<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> name <span style="color: #ff7700;font-weight:bold;">in</span> files:
        <span style="color: #ff7700;font-weight:bold;">if</span> name.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.py'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
          <span style="color: #ff7700;font-weight:bold;">not</span> name.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'__'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> \
          <span style="color: #ff7700;font-weight:bold;">not</span> name.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span>:
            module_name = <span style="color: #483d8b;">'%s.%s.%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>base,
                        <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">basename</span><span style="color: black;">&#40;</span>parent_dir<span style="color: black;">&#41;</span>,
                        name.<span style="color: black;">rsplit</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">sep</span>, <span style="color: #483d8b;">'.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">__import__</span><span style="color: black;">&#40;</span>module_name<span style="color: black;">&#41;</span>
            modules.<span style="color: black;">append</span><span style="color: black;">&#40;</span>module_name<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> modules
&nbsp;
__all__ = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> update__all__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> __all__
    __all__ = <span style="color: black;">&#91;</span>x.<span style="color: black;">rsplit</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> _load_code<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
&nbsp;
update__all__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># intial setup</span></pre></td></tr></table></div>

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

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #007800;">ENV</span>=dev python .<span style="color: #000000; font-weight: bold;">/</span>tester.py
<span style="color: #000000; font-weight: bold;">&lt;</span>module._dev.test.Klass object at 0x9d66e2c<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">in</span> dev
$ <span style="color: #007800;">ENV</span>=model python .<span style="color: #000000; font-weight: bold;">/</span>tester.py
<span style="color: #000000; font-weight: bold;">&lt;</span>module._model.test.Klass object at 0x9435e2c<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">in</span> model
$ <span style="color: #007800;">ENV</span>=prod python .<span style="color: #000000; font-weight: bold;">/</span>tester.py
<span style="color: #000000; font-weight: bold;">&lt;</span>module._prod.test.Klass object at 0x9f12e2c<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">in</span> prod</pre></div></div>

<p><a href="http://johnandkaren.com/blog/wp-content/uploads/2009/02/import_test.tgz">Full source code</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://programmerthoughts.com/programming/three-tier-python-imports/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
