¿No es posible definir múltiples constructores en Python? [duplicate]
⏰ 5 minutos de lectura
cris
Posible duplicado:
¿Cuál es una forma pitónica limpia de tener múltiples constructores en Python?
¿No es posible definir múltiples constructores en Python, con diferentes firmas? Si no, ¿cuál es la forma general de evitarlo?
Por ejemplo, supongamos que desea definir una clase City.
me gustaria poder decir someCity = City() o someCity = City("Berlin")donde el primero solo proporciona un valor de nombre predeterminado y el segundo lo define.
Hazme pensar en esta pregunta – stackoverflow.com/questions/682504/…
– Gante
29 de enero de 2010 a las 18:49
Lo mejor: cómo sobrecargar __init__ método basado en el tipo de argumento?
–Bob Stein
30 de junio de 2017 a las 1:52
Esta pregunta es engañosa en base a la relación del título y el cuerpo. Peor aún, parece ser la respuesta principal en Google; Desearía que se editara o eliminara, ya que la pregunta en el cuerpo es realmente básica. Las respuestas al título se pueden encontrar en el posible enlace duplicado.
– John Smith
23 de julio de 2019 a las 14:57
A diferencia de Java, no puede definir múltiples constructores. Sin embargo, puede definir un valor predeterminado si no se pasa uno.
def __init__(self, city="Berlin"):
self.city = city
mzz
Si sus firmas difieren sólo en el número de argumentos, usar argumentos predeterminados es la forma correcta de hacerlo. Si quieres poder pasar en diferentes tipos de argumento, trataría de evitar la isinstancebasado en el enfoque mencionado en otra respuesta, y en su lugar use argumentos de palabras clave.
Si usar solo argumentos de palabras clave se vuelve difícil de manejar, puede combinarlo con métodos de clase (al código bzrlib le gusta este enfoque). Este es solo un ejemplo tonto, pero espero que entiendas la idea:
class C(object):
def __init__(self, fd):
# Assume fd is a file-like object.
self.fd = fd
@classmethod
def from_filename(cls, name):
return cls(open(name, 'rb'))
# Now you can do:
c = C(fd)
# or:
c = C.from_filename('a filename')
Observe que todos esos métodos de clase siguen pasando por lo mismo __init__pero usar métodos de clase puede ser mucho más conveniente que tener que recordar qué combinaciones de argumentos de palabras clave __init__ trabajar.
isinstance es mejor evitarlo porque el tipo de pato de Python hace que sea difícil averiguar qué tipo de objeto se pasó realmente. Por ejemplo: si desea tomar un nombre de archivo o un objeto similar a un archivo, no puede usar isinstance(arg, file)porque hay muchos objetos similares a archivos que no subclasifican file (como los devueltos por urllib, o StringIO, o…). Por lo general, es una mejor idea que la persona que llama le diga explícitamente a qué tipo de objeto se refería, mediante el uso de diferentes argumentos de palabras clave.
Como usted dice, este es un gran enfoque si necesita pasar diferentes tipos de argumentos. En esos casos tiendo a usar un muy básico __init__ y hacer más de un método de clase para cada caso.
– zekel
26/09/2016 a las 22:20
esta es la solución más generalmente aplicable
– Guilherme de Lázari
13 de abril de 2018 a las 14:36
hay una buena manera (su recomendación) para no ejecutar el habitual __init__ función del segundo constructor? por ejemplo, porque ambos construirán el objeto desde cero
– ThorSummoner
23 de abril de 2019 a las 22:21
pavpanchekha
Para el ejemplo que diste, usa los valores predeterminados:
class City:
def __init__(self, name="Default City Name"):
...
...
En general, tienes dos opciones:
Hacer if–elif bloques basados en el tipo:
def __init__(self, name):
if isinstance(name, str):
# todo
elif isinstance(name, City):
# todo
# todo
Use la tipificación de pato, es decir, suponga que el usuario de su clase es lo suficientemente inteligente como para usarlo correctamente. Esta suele ser la opción preferida.
Telliott99
La respuesta de Jack M. es correcta. Hacerlo de esta forma:
>>> 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
>>>
jack m
La forma más fácil es a través de argumentos de palabras clave:
class City():
def __init__(self, city=None):
pass
someCity = City(city="Berlin")
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
Hazme pensar en esta pregunta – stackoverflow.com/questions/682504/…
– Gante
29 de enero de 2010 a las 18:49
Lo mejor: cómo sobrecargar
__init__
método basado en el tipo de argumento?–Bob Stein
30 de junio de 2017 a las 1:52
Esta pregunta es engañosa en base a la relación del título y el cuerpo. Peor aún, parece ser la respuesta principal en Google; Desearía que se editara o eliminara, ya que la pregunta en el cuerpo es realmente básica. Las respuestas al título se pueden encontrar en el posible enlace duplicado.
– John Smith
23 de julio de 2019 a las 14:57