Ответ 1
В отличие от Java, вы не можете определить несколько конструкторов. Однако вы можете определить значение по умолчанию, если оно не передано.
def __init__(self, city="Berlin"):
self.city = city
Возможный дубликат:
Что такое чистый, pythonic способ иметь несколько конструкторов в Python?
Невозможно ли определить несколько конструкторов в Python с разными сигнатурами? Если нет, то какой общий способ обойти это?
Например, скажем, вы хотели бы определить класс City
Я хотел бы сказать someCity = City()
или someCity = City("Berlin")
, где первый просто дает значение имени по умолчанию, а второе определяет его.
В отличие от Java, вы не можете определить несколько конструкторов. Однако вы можете определить значение по умолчанию, если оно не передано.
def __init__(self, city="Berlin"):
self.city = city
Если ваши подписи отличаются только количеством аргументов с использованием аргументов по умолчанию, это правильный способ сделать это. Если вы хотите иметь возможность передавать различные аргументы, я бы попытался избежать подхода, основанного на isinstance
, упомянутого в другом ответе, вместо этого используя аргументы ключевого слова. Если использование только аргументов ключевого слова становится громоздким, вы можете комбинировать его с classmethods (код bzrlib любит этот подход). Это просто глупый пример, но я надеюсь, что вы поняли:
class C(object):
def __init__(self, fd):
# Assume fd is a file-like object.
self.fd = fd
@classmethod
def fromfilename(cls, name):
return cls(open(name, 'rb'))
# Now you can do:
c = C(fd)
# or:
c = C.fromfilename('a filename')
Обратите внимание, что все эти методы класса все еще проходят через один и тот же __init__
, но использование методов класса может быть гораздо более удобным, чем необходимость запоминать, какие комбинации аргументов ключевого слова __init__
работают.
isinstance
лучше избегать, потому что утиная утиная питона затрудняет определение того, какой объект был фактически передан. Например: если вы хотите взять либо имя файла, либо файл-подобный объект, вы не можете использовать isinstance(arg, file)
потому что существует много файловых объектов, которые не подклассы file
(например, те, которые возвращаются из urllib или StringIO, или...). Как правило, лучше всего просто указать, что вызывающий абонент явно указал вам, какой именно объект имел в виду, используя разные аргументы ключевых слов.
Самый простой способ - использовать аргументы ключевого слова:
class City():
def __init__(self, city=None):
pass
someCity = City(city="Berlin")
Это довольно простой материал, возможно, посмотрите документы python?
В приведенном примере используйте значения по умолчанию:
class City:
def __init__(self, name="Default City Name"):
...
...
В общем, у вас есть два варианта:
1) Сделайте if
- elif
блоки на основе типа:
def __init__(self, name):
if isinstance(name, str):
...
elif isinstance(name, City):
...
...
2) Используйте duck typing --- то есть предположим, что пользователь вашего класса достаточно интеллектуальный, чтобы правильно его использовать. Обычно это предпочтительный вариант.
Джек М. прав, делайте это так:
>>> class City:
... def __init__(self, city=None):
... self.city = city
... def __repr__(self):
... if self.city: return self.city
... return ''
...
>>> c = City('Berlin')
>>> print c
Berlin
>>> c = City()
>>> print c
>>>