Множественный конструктор с Python - PullRequest
8 голосов
/ 20 октября 2010

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

  • a = A (path_to_xml_file)
  • a = A (список A, список B)

Первый метод имеет путь к файлу в качестве входных данных для анализа из файла XML для получения listA и listB. Второй метод дает два списка.

Я могу придумать два способа реализации нескольких конструкторов. Как вы думаете? Какой метод обычно используют парни из Python для этого случая?

Проверьте тип

class A():
    def __init__(self, arg1, arg2 = None):
        if isinstance(arg1, str): 
            ...
        elif isinstance(arg1, list):
            ...

a = A("abc")
b = A([1,2,3],[4,5,6])

Создание разных строителей

class A2():
    def __init__(self):
        pass
    def genFromPath(self, path):
        ...
    def genFromList(self, list1, list2):
        ...
a = A2()
a.genFromPath("abc")
b = A2()
b.genFromList([1,2,3],[4,5,6])

Ответы [ 5 ]

7 голосов
/ 20 октября 2010

Заставьте конструктор взять два списка. Напишите фабричный метод класса, который анализирует XML и возвращает объект.

3 голосов
/ 20 октября 2010

Поскольку количество аргументов, передаваемых инициализатору, отличается в каждом случае, вы можете избежать проверки типов, используя расширенный синтаксис вызова:

class A(object):
    def __init__(self, *args):
        if len(args) == 1:
            path = args[0]
            ...
        elif len(args) == 2:
            list1 = args[0]
            list2 = args[1]
            ...
        else:
            raise SomeException()

3 голосов
/ 20 октября 2010

Используйте classmethod для второго

class A(object):
    @classmethod
    def from_string(cls, string):
        # ...

    @classmethod
    def from_lists(cls, list1, list2):
        # ...

Использовать функции модуля

def from_string(string):
    # ...

def from_lists(list1, list2):
    # ...

class A(object):
    pass
2 голосов
/ 20 октября 2010
class A(object):
    @staticmethod
    def from_string(str):
        obj =A()
        obj.str = str
        return obj

    @staticmethod
    def from_list(lis):
        obj = A()
        obj.lis = lis
        return obj

>>>
(obj1, obj2) = A.from_string('hello'), A.from_list(['one', 'two'])
2 голосов
/ 20 октября 2010

При более внимательном рассмотрении проблемы я бы предложил, чтобы класс взял два списка и включил вспомогательную функцию в модуль:

class A(object):
    def __init__(self, list1, list2):
        # Init from lists here
        pass

def create_A_from_path(path):
    list1, list2 = parse_xml_into_lists(path)
    return A(list1, list2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...