Может быть, он смотрит на Флакс? http://flask.pocoo.org/ Очень простая веб-среда в Python для быстрого создания небольшого веб-сайта.
На самом деле None
намного лучше для "волшебных" значений:
class Cheese():
def __init__(self, num_holes = None):
if num_holes is None:
...
Теперь, если Вы хотите полную свободу добавления большего количества параметров:
class Cheese():
def __init__(self, *args, **kwargs):
#args -- tuple of anonymous arguments
#kwargs -- dictionary of named arguments
self.num_holes = kwargs.get('num_holes',random_holes())
Лучше объяснить понятие *args
и **kwargs
(можно на самом деле изменить эти имена):
def f(*args, **kwargs):
print 'args: ', args, ' kwargs: ', kwargs
>>> f('a')
args: ('a',) kwargs: {}
>>> f(ar='a')
args: () kwargs: {'ar': 'a'}
>>> f(1,2,param=3)
args: (1, 2) kwargs: {'param': 3}
Используя num_holes=None
поскольку значение по умолчанию прекрасно, если Вы собираетесь иметь просто __init__
.
Если Вы хотите несколько, независимых "конструкторов", можно обеспечить их как методы класса. Их обычно называют методами фабрики. В этом случае у Вас могло быть значение по умолчанию для num_holes
быть 0
.
class Cheese(object):
def __init__(self, num_holes=0):
"defaults to a solid cheese"
self.number_of_holes = num_holes
@classmethod
def random(cls):
return cls(randint(0, 100))
@classmethod
def slightly_holey(cls):
return cls(randint(0, 33))
@classmethod
def very_holey(cls):
return cls(randint(66, 100))
Теперь создайте объект как это:
gouda = Cheese()
emmentaler = Cheese.random()
leerdammer = Cheese.slightly_holey()
Все эти ответы превосходны, если Вы хотите использовать дополнительные параметры, но другая возможность Pythonic состоит в том, чтобы использовать classmethod для генерации псевдоконструктора стиля фабрики:
def __init__(self, num_holes):
# do stuff with the number
@classmethod
def fromRandom(cls):
return cls( # some-random-number )
Почему Вы думаете, что Ваше решение является "неуклюжим"? Лично я предпочел бы одного конструктора со значениями по умолчанию по нескольким перегруженным конструкторам в ситуациях как Ваши (Python не поддерживает перегрузку метода так или иначе):
def __init__(self, num_holes=None):
if num_holes is None:
# Construct a gouda
else:
# custom cheese
# common initialization
Для действительно сложных случаев с большим количеством различных конструкторов это могло бы быть более чисто для использования различных функций фабрики вместо этого:
@classmethod
def create_gouda(cls):
c = Cheese()
# ...
return c
@classmethod
def create_cheddar(cls):
# ...
В Вашем примере сыра Вы могли бы хотеть использовать подкласс Gouda Сыра хотя...
Лучший ответ является тем выше о параметрах по умолчанию, но я весело провел время, пишущий это, и он, конечно, отвечает всем требованиям для "нескольких конструкторов". Используйте на Ваш собственный риск.
Что относительно нового метода.
"Типичные реализации создают новый экземпляр класса путем вызова нового суперкласса () метод, использующий супер (currentclass, cls) .new (cls [...]) с соответствующими аргументами и затем изменяющий недавно созданный экземпляр по мере необходимости прежде, чем возвратить его".
Таким образом, у Вас может быть новый метод, изменяют Ваше определение класса путем присоединения соответствующего метода конструктора.
class Cheese(object):
def __new__(cls, *args, **kwargs):
obj = super(Cheese, cls).__new__(cls)
num_holes = kwargs.get('num_holes', random_holes())
if num_holes == 0:
cls.__init__ = cls.foomethod
else:
cls.__init__ = cls.barmethod
return obj
def foomethod(self, *args, **kwargs):
print "foomethod called as __init__ for Cheese"
def barmethod(self, *args, **kwargs):
print "barmethod called as __init__ for Cheese"
if __name__ == "__main__":
parm = Cheese(num_holes=5)
Использовать num_holes=None
как значение по умолчанию, вместо этого. Затем проверьте на ли num_holes is None
, и если так, рандомизировать. Это - то, что я обычно вижу, так или иначе.
Более радикально различные способы строительства могут гарантировать classmethod, который возвращает экземпляр cls
.