Note that there are some explanatory texts on larger screens.

plurals
  1. POUnexpected relative import behavior in Python
    primarykey
    data
    text
    <p>I ran into a very surprising relative import behavior today (unfortantely after nearly 4 hours of pulling my hair out).</p> <p>I have always been under the impression that if you have "Class A" inside of a module name "module_a.py" within a package named "package" that you could equivalently use either:</p> <pre><code>from package.module_a import ClassA </code></pre> <p>or</p> <pre><code>from module_a import ClassA </code></pre> <p>as long as you were importing from a module within "package". I understood this to be a relative import.</p> <p>I never had a problem until today when I needed to check the instance of an object against Class A and I was surprised to find a very unusual behavior.</p> <p>Consider the following:</p> <h2>package/module_a.py</h2> <pre><code>class ClassA(object): pass def check_from_module_a(obj): print 'from module_a' print '-------------' print 'class is:', ClassA print 'object is', type(obj) print 'is obj a ClassA:', isinstance(obj, ClassA) </code></pre> <h2>package/module_b.py</h2> <pre><code>from package.module_a import ClassA from module_a import check_from_module_a a = ClassA() check_from_module_a(a) print ' ' print 'from module_b' print '-------------' print 'class is:', ClassA print 'object is', type(a) print 'is obj a ClassA:', isinstance(a, ClassA) </code></pre> <p>Now when executing module_b.py you get:</p> <pre><code>from module_a ------------- class is: &lt;class 'module_a.ClassA'&gt; object is &lt;class 'package.module_a.ClassA'&gt; is obj a ClassA: False from module_b ------------- class is: &lt;class 'package.module_a.ClassA'&gt; object is &lt;class 'package.module_a.ClassA'&gt; is obj a ClassA: True </code></pre> <p>I have followed the logic and now see why this occurs - it was not real obvious as I assumed that the binding for ClassA was the same regardless of an absolute or relative import. This caused a very nasty bug for me that was very hard to isolate.</p> <p>My questions:</p> <ol> <li><p>Is this the behavior that would be expected? </p></li> <li><p>If this is the logical way that it should work - it is then not clear to me why I would use relative imports if they are not compatible (in the above sense) with absolute imports. Is there a good explanation here that I am missing?</p></li> <li><p>I always assume that relative imports provided additional ease in large refactors when sub package structure might be moved around. Is this the main benefit of a relative import?</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload