La distinción que el autor extrae es que, en lo que se refiere al lenguaje Python, que tiene un objeto válido del tipo especificado antes incluso de entrar en__init__
. Por lo tanto, no es un "constructor", ya que en C++ y teóricamente, un constructor convierte un objeto no válido y preconstruido en un objeto completo "adecuado" del tipo.
Básicamente __new__
en Python se define para devolver "la nueva instancia de objeto", mientras que los operadores nuevos de C++ simplemente devuelven algo de memoria, que aún no es una instancia de ninguna clase.
Sin embargo, __init__
en Python es probablemente donde primero estableces invariantes de clase importantes (qué atributos tiene, solo para empezar). Por lo que respecta a los usuarios de su clase, podría ser un constructor. Es solo que el tiempo de ejecución de Python no se preocupa por ninguno de esos invariantes. Si lo desea, tiene estándares muy bajos para lo que constituye un objeto construido.
Creo que el autor hace un buen punto, y sin duda es una observación interesante sobre la forma en que Python crea los objetos. Sin embargo, es una distinción bastante buena y dudo que llamar al __init__
sea un constructor resultará en código dañado.
Además, observo que la documentación de Python se refiere a __init__
como constructor (http://docs.python.org/release/2.5.2/ref/customization.html)
como un especial restricción en constructores, ningún valor puede ser devuelto
... así que si hay cualquier problema práctico con el pensamiento de __init__
como constructor, a continuación, Python está en problemas!
La forma en que los objetos de construcción de Python y C++ tienen algunas similitudes. Ambos llaman a una función con una responsabilidad relativamente simple (__new__
para una instancia de objeto frente a alguna versión de operator new
para memoria sin procesar), luego ambos llaman a una función que tiene la oportunidad de trabajar más para inicializar el objeto en un estado útil (__init__
frente a constructor).
diferencias prácticas incluyen:
en C++, sin argumentos constructores de clases base son llamados automáticamente en el orden apropiado, si es necesario, mientras que para __init__
en Python, lo que tiene que init explícitamente su base en su propio __init__
. Incluso en C++, debe especificar el constructor de la clase base si tiene argumentos.
en C++, tiene todo un mecanismo para lo que sucede cuando un constructor lanza una excepción, en términos de invocar destructores para subobjetos que ya han sido construidos. En Python creo que el tiempo de ejecución (a lo sumo) llama al __del__
.
Luego está también la diferencia de que __new__
no solo asignar memoria, tiene que devolver una instancia de objeto real. Por otra parte, la memoria bruta no es realmente un concepto que se aplica al código Python.
No estoy seguro de si estoy de acuerdo con 2 ... Como Python es un lenguaje de recolección de basura, el "primer" paso de un constructor en C++ (asignación de memoria) doesn' t debe ejecutarse, y los atributos pueden asignarse a la instancia. Entonces, IMO, '__init__' es un constructor ya que asigna valores a los atributos y completa/finaliza la instancia. –
@Rafe Kettler: en C++, los constructores NO asignan memoria, sino que inicializan y convierten la memoria sin procesar (previamente asignada) en objetos. –
@David: Bien, gracias por la aclaración. Supongo que asignan memoria * a * ese objeto en lugar de asignar memoria en general. –