Неожиданное поведение относительного импорта в Python

Я столкнулся сегодня с очень удивительным относительным поведением импорта (к сожалению, после почти 4 часов выдергивания волос).

У меня всегда было впечатление, что если у вас есть «Класс A» внутри имени модуля «module_a.py» в пакете с именем «package», вы могли бы эквивалентно использовать либо:

from package.module_a import ClassA

, либо

from module_a import ClassA

, пока вы импортировались из модуля в «пакете». Я понял, что это относительное значение.

У меня не было проблем до сегодняшнего дня, когда мне нужно было проверить экземпляр объекта на соответствие классу A, и я был удивлен, обнаружив очень необычное поведение.

Примите во внимание следующее:

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)

Теперь при выполнении module_b.py вы получаете:

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

Я следовал логике и теперь понимаю, почему это происходит - это было не совсем очевидно, поскольку я предполагал, что привязка для ClassA была такой же независимо от абсолютного или относительного значения. Это вызвало у меня очень неприятную ошибку, которую было очень трудно изолировать.

Мои вопросы:

  1. Ожидается ли такое поведение?

  2. Если это логический способ, которым это должно работать - тогда мне непонятно, почему я должен использовать относительный импорт, если он несовместим (в указанном выше смысле) с абсолютным импортом. Есть ли здесь хорошее объяснение того, что мне не хватает?

  3. Я всегда предполагаю, что относительный импорт обеспечивает дополнительную легкость в больших рефакторах, когда структура подпакета может быть перемещена. Является ли это главным преимуществом относительного импорта?

7
задан CharlesB 25 February 2013 в 15:30
поделиться