español __init__ python constructor initialization

python - español - __init__ como constructor?



python__init__ (6)

Sumérgete en Python -

Sería tentador, pero incorrecto, llamar a esto el constructor de la clase. Es tentador, porque parece que un constructor (por convención, __init__ es el primer método definido para la clase), actúa como uno (es el primer código ejecutado en una instancia recién creada de la clase) e incluso suena como uno ("Init" ciertamente sugiere una naturaleza constructor-ish). Incorrecto, porque el objeto ya se ha construido para el momento en que se __init__ , y ya tiene una referencia válida para la nueva instancia de la clase.

La cita sugiere que es incorrecto llamar a __init__ como un constructor porque el objeto ya está construido para el momento en que se __init__ . ¡Pero! Siempre he tenido la impresión de que se llama al constructor solo después de que se construye el objeto porque se usa esencialmente para inicializar los miembros de datos de la instancia, lo que no tendría sentido si el objeto no existía cuando se llamó al constructor. ? (procedente del fondo C ++ / Java)


Constructor devuelve una instancia y puede fallar. Pero __init__ no devuelve una instancia. Incluso cuando __init__ plantea y una excepción, se llama a __del__ para eliminar la instancia.

Esto se puede ver aquí:

class A(object): def __init__(self): raise ValueError def __del__(self): print "Called" def main(): try: a = A() except ValueError, e: print "ValueError" if __name__ == ''__main__'': main()

__new__ por otro lado, devuelve una instancia.


Desde http://www.programiz.com/article/python-self-why

__init__() no es un constructor

[..] Una conclusión importante [..] es que, __init__() no es un constructor. Muchos programadores ingenuos de Python se confunden con él ya que __init__() se llama cuando creamos un objeto. Una inspección más cercana revelará que el primer parámetro en __init__() es el objeto mismo (el objeto ya existe). La función __init__() se __init__() inmediatamente después de que se crea el objeto y se utiliza para inicializarlo.

Técnicamente hablando, constructor es un método que crea el objeto en sí mismo. En Python, este método es __new__() . Una firma común de este método es

__new__(cls, *args, **kwargs)

Con respecto a la respuesta dada por Ben, yo diría que la mayoría de los idiomas no siguen esa definición (completamente).

Además:

Cuando se __new__() , la clase se pasa como el primer argumento automáticamente. Esto es para lo que es la cls en la firma de arriba. Nuevamente, como self , cls es solo una convención de nombres. Además, *args y **kwargs se utilizan para tomar una cantidad arbitraria de argumentos durante las llamadas a métodos en Python.

Algunas cosas importantes para recordar al implementar __new__() son:

  1. __new__() siempre se llama antes de __init__() .
  2. El primer argumento es la clase misma que se pasa de manera implícita.
  3. Siempre devuelve un objeto válido de __new__() . No es obligatorio, pero ese es el punto.

Bottomline (para mí): __new__() parece ser el constructor, no __init__() aunque -por todos los medios prácticos __init__() hace parte de lo que la mayoría de la gente piensa que hará un constructor.


En "Programming Python: Introduction to Computer Science" de John Zelle dice: " El método especial __init__ es el constructor de objetos . Python llama a este método para inicializar un nuevo objeto. El rol de __init__ es proporcionar valores iniciales para las variables de instancia de un objeto."


Personalmente, considero que " __init__ no es un constructor" para ser bastante fino.

__init__ se __init__ cuando se solicita un nuevo objeto. Se supone que debe usar sus argumentos para asignar atributos al nuevo objeto, de modo que se configuren las invariantes requeridas para el funcionamiento normal del objeto. El objeto ya es un lugar preexistente válido para almacenar atributos para cuando el código en __init__ comience a ejecutarse. El nuevo objeto normalmente ya no tiene atributos definidos cuando el código en __init__ comienza a ejecutarse (aparte de los que poseen todos los objetos).

Se llama a un constructor de C ++ cuando se solicita un nuevo objeto. Se supone que debe usar sus argumentos para asignar campos al nuevo objeto, de modo que se configuren las invariantes requeridas para el funcionamiento normal del objeto. El objeto ya es un lugar preexistente válido para almacenar campos en el momento en que el código en el constructor comienza a ejecutarse. El nuevo objeto ya tiene todos sus campos declarados cuando el código en el constructor comienza a ejecutarse, pero contienen basura.

Se llama a un constructor de Java cuando se solicita un nuevo objeto. Se supone que debe usar sus argumentos para asignar campos al nuevo objeto, de modo que se configuren las invariantes requeridas para el funcionamiento normal del objeto. El objeto ya es un lugar preexistente válido para almacenar campos en el momento en que el código en el constructor comienza a ejecutarse. El nuevo objeto ya tiene todos sus campos declarados cuando el código en el constructor comienza a ejecutarse, con sus valores predeterminados.

La principal diferencia entre un método __init__ y un constructor C ++ / Java está en la última frase que he resaltado, y esa es solo la diferencia entre la naturaleza estática de Java / C ++ y la naturaleza dinámica de Python. No creo que esto justifique llamarlos conceptos fundamentalmente diferentes a los que no debe referirse la misma palabra.

Creo que la principal razón por la que a los Pythonistas no les gusta referirse a __init__ como un constructor es que la gente piensa que los constructores C ++ / Java "hacen un nuevo objeto", porque eso es lo que parecen hacer cuando los llamas. Pero realmente hay dos cosas sucediendo cuando llamas a un constructor; se crea un nuevo objeto y luego se llama al constructor para inicializarlo. En C ++ / Java, la parte de "crear un objeto nuevo" es invisible, mientras que se puede exponer / personalizar en Python (a través del método __new__ ).

Entonces, aunque el rol del método __init__ es muy similar al rol de un constructor de C ++ / Java, algunas personas prefieren enfatizar el hecho de que este no es todo el proceso al decir que " __init__ no es un constructor".


Si tienes una clase Foo entonces:

  • Foo() es el constructor
  • Foo.__init__() es el iniciador
  • Foo.__new__() es el asignador

La construcción de un objeto Python es simplemente la asignación de una nueva instancia seguida de la inicialización de dicha instancia.


__init__ no es un constructor, pero por razones que no le importan a medida que aprende Python. Se comporta de la manera que estás acostumbrado a que los constructores se comporten en C ++ y Java.