How do I import a submodule with web2py?
<p>I'm trying to do a dynamic import (using "__import__()") of a submodule in web2py and it doesn't seem to be finding the submodule.</p>

<p>Here's an example path:
web2py/app/modules/module.py &lt;-- This works
web2py/app/modules/module_folder/submodule.py &lt;-- This won't get spotted.</p>

<p>Right now as a workaround I'm using 'exec()' but I'd rather not do that.</p>

<hr>

<p><strong>Answers to questions:</strong></p>

<p><em>"Do you have __init__.py in module_folder?"</em></p>

<p>Yep.</p>

<p><em>"What exactly is the line of code you write to import web2py/app/modules/module_folder/submodule.py?"</em></p>

<pre><code>mapping_module = __import__('communication_templates.mappings.%s' % module_name)
</code></pre>

<p><em>"what is the error?"</em></p>

<pre><code>&lt;type 'exceptions.AttributeError'&gt; 'module' object has no attribute 'mapping_dict'
</code></pre>

<p>Explanation: I'm trying to get a variable named 'mapping_dict' from the module once I've loaded it.</p>

<p>The problem here is that <code>__import__</code> does not do the most intuitive thing (neither does <code>import</code> btw).</p>

<p>Here's what happens:</p>

<pre><code>&gt;&gt;&gt; import sys
&gt;&gt;&gt; x = __import__('package1.package2.module')
&gt;&gt;&gt; x
&lt;module 'package1' from 'C:\\Temp\\package1\\__init__.py'&gt;
</code></pre>

<p>Even though <code>package1.package2.module</code> was imported, the variable returned is actually <code>package1</code>.</p>

<p>So, to access something that is in <code>package1.package2.module</code>, one has to dig down again:</p>

<pre><code>&gt;&gt;&gt; x.package2.module.Class
&lt;class 'package1.package2.module.Class'&gt;
</code></pre>

<p><strong>Is it then the same as importing just <code>package1</code>?</strong></p>

<p>Not really:</p>

<pre><code>&gt;&gt;&gt; x = __import__('package1')
&gt;&gt;&gt; x
&lt;module 'package1' from 'C:\\Temp\\package1\\__init__.py'&gt;
&gt;&gt;&gt; x.package2.module.Class
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
AttributeError: module 'package1' has no attribute 'package2'
</code></pre>

<h2>Why?</h2>

<p>Well, <code>__import__</code> is the same as `import, that is, these are the same:</p>

<pre><code>package1 = __import__('package1.package2.module')
# is the same as:
import package1.package2.module
</code></pre>

<p>And:</p>

<pre><code>package1 = __import__('package1')
# is the same as:
import package1
</code></pre>

<p>In each of those cases, you get just one local variable <code>package1</code>.</p>

<p>In the case of importing <code>package1.package2.module</code>, <code>package2</code> is also imported and stored in <code>package2</code> attribute of package <code>package1</code> etc.</p>

<h1>Solution</h1>

<p>To access <code>package1.package2.module.Class</code>, if <code>package1.package2.module</code> is in a string:</p>

<pre><code>&gt;&gt;&gt; s = 'package1.package2.module'
&gt;&gt;&gt; module = __import__(s)
&gt;&gt;&gt; for submodule_name in s.split('.')[1:]:
...     module = getattr(module, submodule_name)
...
&gt;&gt;&gt; module.Class
&lt;class 'package1.package2.module.Class'&gt;
</code></pre>

python web2py