Today I have a very surprising relative import behavior (unsatisfactory after almost four hours of hair pulling).
I always got the impression that if you have "class A" inside the module name "module_a.py" in a package called "package" that you could use the same way either:
from package.module_a import ClassA
or
from module_a import ClassA
while you import from the module into a "package". I realized that this is a relative import.
I have never had a problem until today, when I needed to check an instance of an object against class A, and I was surprised to find very unusual behavior.
Consider the following:
package / module _a.py
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)
package / module _b.py
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)
Now when you execute module_b.py you get:
from module_a ------------- class is: <class 'module_a.ClassA'> object is <class 'package.module_a.ClassA'> is obj a ClassA: False from module_b ------------- class is: <class 'package.module_a.ClassA'> object is <class 'package.module_a.ClassA'> is obj a ClassA: True
I followed the logic and now understand why this is happening - this was not entirely obvious, since I assumed that the binding for ClassA was the same regardless of absolute or relative imports. This caused a very unpleasant mistake for me, which was very difficult to isolate.
My questions:
Is this behavior you would expect?
If this is the logical way it should work, then I donβt understand why I would use relative imports if they are incompatible (in the indicated sense) with absolute imports. Is there a good explanation here that I am missing?
I always assume that relative imports provided extra simplicity in large refactors when the subpackage structure could move. Is this the main advantage of relative imports?
Rockman
source share