Одна из основных мотиваций для использования абстрактного класса должна включить полиморфизм в рамках Вашего приложения - т.е.: можно заменить различной версией во времени выполнения. На самом деле это - почти такая же вещь, поскольку использование интерфейса кроме абстрактного класса обеспечивает некоторую общую инфраструктуру, часто называемую Шаблонный шаблон .
С точки зрения поблочного тестирования, существует две вещи рассмотреть:
Взаимодействие Вашего абстрактного класса со связанные классы . Используя ложную среду тестирования идеально для этого сценария, поскольку он показывает, что Ваш абстрактный класс играет хорошо с другими.
Функциональность производных классов . Если у Вас есть пользовательская логика, которую Вы записали для своих производных классов, необходимо протестировать те классы в изоляции.
редактирование: RhinoMocks является потрясающей ложной средой тестирования, которая может генерировать фиктивные объекты во времени выполнения путем динамичного получения из класса. Этот подход может сохранить Вас бесчисленные часы кодирующих руку производных классов.
Вот почему абсолютный импорт был выбран в качестве нового поведения по умолчанию. Однако они еще не используются по умолчанию в 2.6 (возможно, в 2.7 ...). Вы можете узнать их поведение сейчас, импортировав их из будущего:
from __future__ import absolute_import
Вы можете узнать больше об этом в PEP, созданном Ником, или (я думаю, что проще понять) в документе «Что нового в Python 2.5 ".
Переименуйте его . Это идея пространств имен. ваш openid
может быть подмодулем в вашем проекте верхнего модуля
. ваш адрес электронной почты
будет конфликтовать с адресом верхнего модуля электронной почты
в stdlib.
поскольку ваш openid не универсален, он представляет собой особый случай для вашего проекта.
Я не буду вдаваться в полемику по поводу переименования, а вместо этого сосредоточусь на том, чтобы показать вам, как делать то, что вы хотите («хорошо ли это для вас» или нет ;-). Решение несложное ...
Просто установите __ path __
! Небольшая демонстрация:
$ mkdir /tmp/modules /tmp/packages
$ mkdir /tmp/packages/openid
$ echo 'print "Package!"' > /tmp/packages/openid/__init__.py
$ gvim /tmp/modules/openid.py
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid'
Module!
Package!
здесь показан модуль openid, способный импортировать одноименный пакет , даже если путь к модулю указан раньше в sys.path, и sys .modules ['openid']
явно уже установлен в то время. И весь «секрет» находится в простом коде openid.py ...:
print "Module!"
__path__ = ['/tmp/packages']
import openid
без назначения __ path __
, конечно, будет выдан только Module!
.
Также работает, конечно, для импорта подмодулей внутри пакета. Сделайте:
$ echo 'print "Submod!"' > /tmp/packages/openid/submod.py
и измените openid.py ' В последней строке
from openid import submod
вы увидите:
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid'
Module!
Package!
Submod!
$
Вы можете использовать относительный или абсолютный импорт (в зависимости от специфики вашей ситуации), который описан в PEP 328 совсем недавно. Конечно, серьезно, вы не должны создавать подобные конфликты именования и должны переименовать свой файл.
Вы можете попробовать перемешать sys.path
, чтобы переместить интересующие каталоги на передний план, прежде чем выполнять импорт.