Я создаю модуль Python с требованием, чтобы конечный пользователь этого модуля мог выбрать конкретную реализацию класса, которая будет использоваться различными другими классами в модуле (предпочтительно с реализацией по умолчанию).
Одним из ограничений является то, что этот класс встроен в глубокие иерархии.Вот минимальный пример, иллюстрирующий проблему:
class X():
pass
class Y():
pass
Z = X # or Z = Y
class A():
def __init__(self):
self.zoo = Z()
class B():
def __init__(self):
self.zoo = Z()
class C(B):
pass
Для целей этого примера я использовал глобальную переменную Z
, чтобы определить, какой класс будет выбран.Это действительно не идеально и требует от пользователя monkey patch / изменения глобальной переменной после импорта.Это также предотвращает смешивание различных реализаций в одном и том же проекте.
from my_module import A, B, C, Y, Z
Z=Y
class U():
def __init__():
self.foo = C()
Какой способ решения этой проблемы вы предпочитаете?Я хотел бы избежать передачи класса в качестве параметра конструктора, поскольку выбор, например, X
или Y
должен быть связан с классом, а не с экземпляром.Поскольку Python не поддерживает параметризованный импорт, я думал о декораторах и метаклассах, но не смог придумать чистый дизайн.