What is a clean "pythonic" way to implement multiple constructors?
Каков чистый "питонический" способ реализации нескольких конструкторов?
Я не могу найти окончательного ответа на этот вопрос. Насколько я знаю, у вас не может быть нескольких __init__ функций в классе Python. Итак, как мне решить эту проблему?
Предположим, у меня есть класс с именем Cheese со свойством number_of_holes. Как я могу иметь два способа создания объектов cheese...
Тот, который требует такого количества отверстий, как это: parmesan = Cheese(num_holes=15).
И тот, который не принимает аргументов и просто рандомизирует number_of_holes свойство: gouda = Cheese().
Я могу придумать только один способ сделать это, но он кажется неуклюжим:
Использование num_holes=None по умолчанию подойдет, если вы собираетесь использовать только __init__.
Если вам нужно несколько независимых "конструкторов", вы можете предоставить их в виде методов класса. Обычно их называют заводскими методами. В этом случае вы могли бы использовать значение по умолчанию для num_holes be 0.
classCheese(object): def__init__(self, num_holes=0): "defaults to a solid cheese" self.number_of_holes = num_holes
Определенно следует предпочесть уже опубликованные решения, но поскольку никто еще не упомянул это решение, я думаю, его стоит упомянуть для полноты картины.
@classmethod Подход может быть изменен, чтобы предоставить альтернативный конструктор, который не вызывает конструктор по умолчанию (__init__). Вместо этого экземпляр создается с помощью __new__.
Это может быть использовано, если тип инициализации не может быть выбран на основе типа аргумента конструктора, и конструкторы не совместно используют код.
@classmethod deffrom_somewhere(cls, somename): obj = cls.__new__(cls) # Does not call __init__ super(MyClass, obj).__init__() # Don't forget to call any polymorphic base class initializers obj._value = load_from_somewhere(somename) return obj
Ответ 4
Все эти ответы превосходны, если вы хотите использовать необязательные параметры, но другая возможность Pythonic заключается в использовании метода classmethod для создания псевдоконструктора в заводском стиле: