Фабрика классов в Python

Это то, что я сделал в OS X:

git mv File file.tmp
git mv file.tmp file

Два шага, потому что в противном случае я получил ошибку «файл существует». Возможно, это можно сделать за один шаг, добавив --cached или такой.

64
задан smith 14 December 2013 в 23:13
поделиться

3 ответа

Принятие Вас должно разделить классы для различных регистраторов (хотя это не очевидно в Вашем примере), Ваша внешность решения хорошо, хотя RegistrarA и RegistrarB, вероятно, совместно использует функциональность и мог быть получен из Абстрактный базовый класс .

Как альтернатива Вашему factory функция, Вы могли указать dict, отобразившись на Ваши классы регистратора:

Registrar = {'test.com': RegistrarA, 'test.biz': RegistrarB}

Затем:

registrar = Registrar['test.com'](domain)

Один каламбур: Вы действительно не делаете Фабрики классов здесь, поскольку Вы возвращаете экземпляры, а не классы.

23
ответ дан Jeff Bauer 14 December 2013 в 23:13
поделиться

Я думаю с помощью функции, прекрасен.

более интересный вопрос состоит в том, как Вы определяете который регистратор загрузиться? Одна опция состоит в том, чтобы иметь абстрактный класс Регистратора, который конкретные реализации разделяют на подклассы, затем выполняют итерации по __subclasses__() вызов is_registrar_for() метод класса:

class Registrar(object):
  def __init__(self, domain):
    self.domain = domain

class RegistrarA(Registrar):
  @classmethod
  def is_registrar_for(cls, domain):
    return domain == 'foo.com'

class RegistrarB(Registrar):
  @classmethod
  def is_registrar_for(cls, domain):
    return domain == 'bar.com'


def Domain(domain):
  for cls in Registrar.__subclasses__():
    if cls.is_registrar_for(domain):
      return cls(domain)
  raise ValueError


print Domain('foo.com')
print Domain('bar.com')

Это позволит Вам прозрачно добавить новый Registrar с и делегировать решение, которых доменов каждый поддерживает им.

75
ответ дан Alec Thomas 14 December 2013 в 23:13
поделиться

В Python можно изменить фактический класс непосредственно:

class Domain(object):
  def __init__(self, domain):
    self.domain = domain
    if ...:
      self.__class__ = RegistrarA
    else:
      self.__class__ = RegistrarB

И затем следующее будет работать.

com = Domain('test.com') #load RegistrarA
com.lookup()

я использую этот подход успешно.

11
ответ дан bialix 14 December 2013 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: