Эта статья о том, как важно быть последовательным. А также о том, почему иногда могут не работать проверки идентичности и наследования классов, и проверки принадлежности объекта к классу.
Пожалуй, большую часть из того, что я хочу сейчас вам рассказать правильнее было бы выразить в коде. Для наглядости. Итак, приступим:

#!/usr/bin/env python3
'''
Тестируем влияние импорта на проверки идентичности классов.
* Создать директорию `imptest`.
* Переместиться в директорию `imptest`
* В директории `imptest` создать пустой файл `__init__.py`.
* В директории `imptest` создать файл `test.py`, поместить в него этот код.
* В директории `imptest` создать файл `class_a.py`.
* Поместить в `class_a.py` следующий код:
class A(object):
pass
* Запустить `test.py`
> python3 test.py
* Изучить результат.
'''
import sys
from os import path
sys.path.insert(0, path.dirname(path.dirname(path.realpath(__file__))))
from class_a import A
from imptest.class_a import A as AA
print('\nИмпортируем один и тот же класс разными способами:')
print('from class_a import A')
print('from imptest.class_a import A as AA')
print()
print('A==A --> %s' % (A==A))
print('AA==A --> %s' % (AA==A))
print('isinstance(AA(), A) --> %s' % isinstance(AA(), A))
print('\nПроход по атрибутам:')
for attr in dir(A):
if attr == '__dict__':
continue
val_a, val_aa = getattr(A, attr), getattr(AA, attr)
if val_a != val_aa:
print(' Разл.: %s' % attr)
if isinstance(val_a, str):
print(' "%s" VS "%s"' % (val_a, val_aa))
print('\nПроход по sys.modules:')
for mod_name in sys.modules.keys():
if mod_name.find('class_a') > -1:
print(' Найден %s' % mod_name)
print('\nБудьте последовательны в вопросах импорта.')
print('Да и в прочих тоже.')
print()
view raw test.py hosted with ❤ by GitHub

Наверное, после запуска этого кода, особых пояснений больше не потребуется, однако пару слов я всё же скажу.

Итак, механизм импорта честно отрабатывает, выполняя то, что ему поручили, и в sys.modules появляется два разных модуля. Импортированный разными способами один и тот же класс, различается, помимо прочего, атрибутом __module__, который был проставлен в момент создания типа.

И, если вам вдруг интересно, где (помимо этого странного кода выше) можно натолкнуться на такое поведение, то я скажу, что в любых проектах со множеством [вложенных] модулей есть такой шанс. Например, в Django, создатели которого вовсе не зря советуют придерживаться одного стиля импорта, не мешать абсолютные с относительными.

Будьте последовательны, не забывайте про тесты.
Удачи!

Категории

Область
Интерпретатор
ЯП
Проект

На заметку
Зарегистрированные пользователи могут оценивать Книги, Видео, Статьи и прочее, а также добавлять их в избранное, для упрощения доступа к ним в будущем.