Exception Class Failed to Import
<p>I have two files.  One is <code>program_utils.py</code> with the contents:</p>

<pre><code>class SomeException(Exception):
    def __init__(self, *args, **kwargs):
        Exception.__init__(self, *args, **kwargs)
</code></pre>

<p>another, say, <code>program.py</code>, with </p>

<pre><code>import program_utils

def SomeFunction(arg):
    if arg in set([ok_val1, ok_val2]):
        # do something
    else:
        raise SomeException('reason')
</code></pre>

<p>When I run <code>program.py</code> it complains: <code>NameError: name 'MyException' is not defined</code>.  When I paste the contents of <code>program_utils.py</code> directly into <code>program.py</code>, it works fine.  Why?</p>

<p>Unlike <code>#include</code> in <code>C</code>/<code>C++</code>, in python the <code>import</code> statement is not equivalent to copy/pasting the file into your file.</p>

<p>If you want that behavior, you can sort of get it by doing:</p>

<pre><code>from program_utils import *
</code></pre>

<p>However, there are some caveats. e.g.: if you are importing a package, the <code>__all__</code> variable in the <code>__init__.py</code> controls which symbols get imported whtin doing <code>from foo import *</code>.</p>

<p>In general, <code>from foo import *</code> is not a very good practice. You don't necessarily know what symbols you are importing. Additionally you may overwrite the value of some symbols if you do that with more than one module and they both define the same symbol(s).</p>

<p>Arguably it is also somewhat more clear what is going on if you use the module name when using its symbols. i.e.:</p>

<pre><code>foo.bar()
</code></pre>

<p>vs</p>

<pre><code>from foo import *
...
from spam import *

bar()
</code></pre>

<p>In the second case it might not be obvious that <code>bar</code> came from the foo module.</p>

<p>There is a (small) performance consideration. If you end up doing <code>foo.bar()</code> a lot, you are actually doing an unnecessary dictionary lookup because every time, the interpreter looks up <code>'bar'</code> in <code>foo.__dict__</code>. To fix that, you can do:</p>

<pre><code>from foo import bar
</code></pre>

python exception python-import