Python __init__ y yo, ¿qué hacen?

Estoy aprendiendo el lenguaje de progtwigción Python y encontré algo que no entiendo completamente.

En un método como:

def method(self, blah): def __init__(?): .... .... 

¿Qué hace el self ? ¿Qué se supone que debe ser? ¿Es obligatorio?

¿Qué hace el método __init__ ? ¿Por qué es necesario? (etc.)

Creo que podrían ser construcciones OOP, pero no sé mucho.

En este código:

 class A(object): def __init__(self): self.x = 'Hello' def method_a(self, foo): print self.x + ' ' + foo 

… la self variable representa la instancia del objeto en sí. La mayoría de los lenguajes orientados a objetos pasan esto como un parámetro oculto a los métodos definidos en un objeto; Python no lo hace. Tienes que declararlo explícitamente. Cuando creas una instancia de la clase A y llamas a sus métodos, se pasará automáticamente, como en …

 a = A() # We do not pass any argument to the __init__ method a.method_a('Sailor!') # We only pass a single argument 

El método __init__ es aproximadamente lo que representa un constructor en Python. Cuando llama a A() Python crea un objeto para usted y lo pasa como primer parámetro al método __init__ . Cualquier parámetro adicional (por ejemplo, A(24, 'Hello') ) también se pasará como argumentos; en este caso, se generará una excepción, ya que el constructor no los espera.

Sí, tienes razón, estas son construcciones oop.

__init__ es el constructor de una clase. El parámetro self se refiere a la instancia del objeto (como this en C ++).

 class Point: def __init__(self, x, y): self._x = x self._y = y 

El método __init__ se llama cuando se asigna memoria para el objeto:

 x = Point(1,2) 

Es importante utilizar el parámetro self en el método de un objeto si desea mantener el valor con el objeto. Si, por ejemplo, implementas el método __init__ esta manera:

 class Point: def __init__(self, x, y): _x = x _y = y 

Los parámetros x e y se almacenarán en las variables de la stack y se descartarán cuando el método init salga del scope. Al establecer esas variables como self._x y self._y establece esas variables como miembros del objeto Point (accesible durante la vida útil del objeto).

Un breve ejemplo ilustrativo.

Con la esperanza de que pueda ayudar un poco, aquí hay un ejemplo simple que utilicé para entender la diferencia entre una variable declarada dentro de una clase y una variable declarada dentro de una función __init__ :

 class MyClass(object): i = 123 def __init__(self): self.i = 345 a = MyClass() print ai 345 print MyClass.i 123 

En breve:

  1. self como sugiere, se refiere a sí mismo , el objeto que ha llamado el método. Es decir, si tiene N objetos que llaman al método, self.a se referirá a una instancia separada de la variable para cada uno de los N objetos. Imagina N copias de la variable a para cada objeto.
  2. __init__ es lo que se llama un constructor en otros lenguajes OOP como C ++ / Java. La idea básica es que se trata de un método especial al que se llama automáticamente cuando se crea un objeto de esa Clase.

__init__ actúa como un constructor. Deberá pasar “self” a cualquier función de clase como primer argumento si desea que se comporten como métodos no estáticos. “self” son variables de instancia para su clase.

Prueba este código. Espero que ayude a muchos progtwigdores de C como yo a aprender Py.

 #! /usr/bin/python2 class Person: '''Doc - Inside Class ''' def __init__(self, name): '''Doc - __init__ Constructor''' self.n_name = name def show(self, n1, n2): '''Doc - Inside Show''' print self.n_name print 'Sum = ', (n1 + n2) def __del__(self): print 'Destructor Deleting object - ', self.n_name p=Person('Jay') p.show(2, 3) print p.__doc__ print p.__init__.__doc__ print p.show.__doc__ 

Salida:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay

Tuve problemas para entender esto yo mismo. Incluso después de leer las respuestas aquí.

Para entender correctamente el método __init__ , necesitas entenderte a ti mismo.

El auto parametro

Los argumentos aceptados por el método __init__ son:

 def __init__(self, arg1, arg2): 

Pero en realidad solo le pasamos dos argumentos:

 instance = OurClass('arg1', 'arg2') 

¿De dónde viene el argumento extra?

Cuando accedemos a los atributos de un objeto, lo hacemos por nombre (o por referencia). Aquí la instancia es una referencia a nuestro nuevo objeto. Accedemos al método printargs del objeto de instancia utilizando instance.printargs.

Para acceder a los atributos del objeto desde el método __init__ necesitamos una referencia al objeto.

Cuando se llama a un método, se pasa una referencia al objeto principal como primer argumento. Por convención, siempre llamas este primer argumento a tus propios métodos.

Esto significa que en el método __init__ podemos hacer:

 self.arg1 = arg1 self.arg2 = arg2 

Aquí estamos configurando atributos sobre el objeto. Puedes verificar esto haciendo lo siguiente:

 instance = OurClass('arg1', 'arg2') print instance.arg1 arg1 

Los valores de este tipo se conocen como atributos de objeto. Aquí el método __init__ establece los atributos arg1 y arg2 de la instancia.

fuente: http://www.voidspace.org.uk/python/articles/OOP.shtml#the-init-method

tenga en cuenta que self podría ser cualquier identificador válido de Python. Por ejemplo, podríamos escribir fácilmente, a partir del ejemplo de Chris B:

 class A(object): def __init__(foo): foo.x = 'Hello' def method_a(bar, foo): print bar.x + ' ' + foo 

Y funcionaría exactamente igual. Sin embargo, se recomienda usar uno mismo porque otros pitones lo reconocerán más fácilmente.

Básicamente, debe usar la palabra clave ‘self’ cuando use una variable en múltiples funciones dentro de la misma clase. En cuanto a init , se usa para configurar valores predeterminados en caso de que no se llame a ninguna otra función dentro de esa clase.

  1. __init__ es básicamente una función que “inicializará” / “activará” las propiedades de la clase para un objeto específico, una vez creado y combinado con la clase correspondiente.
  2. self representa ese objeto que heredará esas propiedades.

Los objetos de clase admiten dos tipos de operaciones: referencias de atributos y creación de instancias.

Las referencias de atributos utilizan la syntax estándar utilizada para todas las referencias de atributos en Python: obj.name. Los nombres de atributo válidos son todos los nombres que estaban en el espacio de nombres de la clase cuando se creó el objeto de clase. Entonces, si la definición de la clase se veía así:

 class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world' 

luego MyClass.i y MyClass.f son referencias de atributo válidas, que devuelven un entero y un objeto de función, respectivamente. Los atributos de clase también se pueden asignar a, por lo que puede cambiar el valor de MyClass.i por asignación. __doc__ también es un atributo válido, devolviendo la cadena de documentación que pertenece a la clase: “Una clase de ejemplo simple”.

La creación de instancias de clase utiliza la notación de funciones. Simplemente simule que el objeto de clase es una función sin parámetros que devuelve una nueva instancia de la clase. Por ejemplo:

 x = MyClass() 

La operación de creación de instancias (“llamar” a un objeto de clase) crea un objeto vacío. A muchas clases les gusta crear objetos con instancias personalizadas a un estado inicial específico. Por lo tanto, una clase puede definir un método especial llamado __init__() , como este:

 def __init__(self): self.data = [] 

Cuando una clase define un __init__() , la __init__() instancias de clase invoca automáticamente __init__() para la instancia de clase recién creada. Entonces, en este ejemplo, se puede obtener una nueva instancia inicializada por:

 x = MyClass() 

Por supuesto, el __init__() puede tener argumentos para una mayor flexibilidad. En ese caso, los argumentos dados al operador de __init__() instancias de clase se pasan a __init__() . Por ejemplo,

 class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart x = Complex(3.0, -4.5) xr, xi 

Tomado de la documentación oficial que más me ayudó al final.


Aquí está mi ejemplo

 class Bill(): def __init__(self,apples,figs,dates): self.apples = apples self.figs = figs self.dates = dates self.bill = apples + figs + dates print ("Buy",self.apples,"apples", self.figs,"figs and",self.dates,"dates. Total fruitty bill is",self.bill," pieces of fruit :)") 

Cuando creas instancia de clase Bill:

 purchase = Bill(5,6,7) 

Usted obtiene:

 > Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18 pieces of > fruit :) 

El ‘self’ es una referencia a la instancia de clase.

 class foo: def bar(self): print "hi" 

Ahora podemos crear una instancia de foo y llamar al método, Python agrega el parámetro automático en este caso:

 f = foo() f.bar() 

Pero también se puede pasar si la llamada al método no está en el contexto de una instancia de la clase, el siguiente código hace lo mismo.

 f = foo() foo.bar(f) 

Curiosamente, el nombre variable “self” es solo una convención. La siguiente definición funcionará exactamente igual. Habiendo dicho que es una convención muy fuerte que debe seguirse siempre , pero dice algo sobre la naturaleza flexible del lenguaje.

 class foo: def bar(s): print "hi" 
 # Source: Class and Instance Variables # https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables class MyClass(object): # class variable my_CLS_var = 10 # sets "init'ial" state to objects/instances, use self argument def __init__(self): # self usage => instance variable (per object) self.my_OBJ_var = 15 # also possible, class name is used => init class variable MyClass.my_CLS_var = 20 def run_example_func(): # PRINTS 10 (class variable) print MyClass.my_CLS_var # executes __init__ for obj1 instance # NOTE: __init__ changes class variable above obj1 = MyClass() # PRINTS 15 (instance variable) print obj1.my_OBJ_var # PRINTS 20 (class variable, changed value) print MyClass.my_CLS_var run_example_func() 

En este código:

 class Cat: def __init__(self, name): self.name = name def info(self): print 'I am a cat and I am called', self.name 

Aquí __init__ actúa como un constructor para la clase y cuando se __init__ una instancia de un objeto, se llama a esta función. self representa el objeto de creación de instancias.

 c = Cat('Kitty') c.info() 

El resultado de las afirmaciones anteriores será el siguiente:

 I am a cat and I am called Kitty 

Solo una demo para la pregunta.

 class MyClass: def __init__(self): print('__init__ is the constructor for a class') def __del__(self): print('__del__ is the destructor for a class') def __enter__(self): print('__enter__ is for context manager') return self def __exit__(self, exc_type, exc_value, traceback): print('__exit__ is for context manager') def greeting(self): print('hello python') if __name__ == '__main__': with MyClass() as mycls: mycls.greeting() 

 $ python3 class.objects_instantiation.py __init__ is the constructor for a class __enter__ is for context manager hello python __exit__ is for context manager __del__ is the destructor for a class 

Python __init__ y self ¿qué hacen?

¿Qué hace el self ? ¿Qué se supone que debe ser? ¿Es obligatorio?

¿Qué hace el método __init__ ? ¿Por qué es necesario? (etc.)

El ejemplo dado no es correcto, así que permítame crear un ejemplo correcto basado en él:

 class SomeObject(object): def __init__(self, blah): self.blah = blah def method(self): return self.blah 

Cuando creamos una instancia del objeto, se llama a __init__ para personalizar el objeto después de que se haya creado. Es decir, cuando llamamos a SomeObject con 'blah' continuación (lo que podría ser cualquier cosa), se pasa a la función __init__ como argumento, blah :

 an_object = SomeObject('blah') 

El argumento self es la instancia de SomeObject que se asignará a an_object .

Más adelante, podríamos querer llamar a un método en este objeto:

 an_object.method() 

Al realizar la búsqueda punteada, es decir, an_object.method , vincula la instancia a una instancia de la función, y el método (como se llama anteriormente) ahora es un método “vinculado”, lo que significa que no necesitamos pasar la instancia explícitamente a El método de llamada.

La llamada al método obtiene la instancia porque estaba vinculada a la búsqueda de puntos, y cuando se llama, ejecuta el código para el que estaba progtwigda.

El self argumento implícitamente pasado se llama self por convención. Podríamos usar cualquier otro nombre legal de Python, pero es probable que otros progtwigdores de Python lo empantenen y lo utilicen si lo cambian por otro.

__init__ es un método especial, documentado en la documentación del modelo de datos de Python . Se llama inmediatamente después de que se crea la instancia (generalmente a través de __new__ , aunque __new__ no es necesario a menos que esté subclasificando un tipo de datos inmutable).

¿Qué hace el yo ? ¿Qué se supone que debe ser? ¿Es obligatorio ?

El primer argumento de cada método de clase, incluido init, es siempre una referencia a la instancia actual de los clas s. Por convención, este argumento siempre se denomina self. En el método init, self se refiere al objeto recién creado; en otros métodos de clase, se refiere a la instancia cuyo método fue llamado.

Python no te obliga a usarself “. Puedes darle el nombre que quieras. Pero recuerde que el primer argumento en una definición de método es una referencia al objeto.Python agrega el argumento propio a la lista para usted; no necesita incluirlo cuando llama a los métodos. Si no se proporcionó el método init en sí mismo, obtendrá un error.

 TypeError: __init___() takes no arguments (1 given) 

¿Qué hace el método init ? ¿Por qué es necesario? (etc.)

inicio corto para la inicialización. Es un constructor al que se llama cuando crea una instancia de la clase y no es necesario . Pero normalmente nuestra práctica es escribir el método init para establecer el estado predeterminado del objeto. Si no está dispuesto a establecer ningún estado del objeto inicialmente, no necesita escribir este método.

Aquí, el chico ha escrito bastante bien y es simple: https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/

Lea el enlace de arriba como una referencia a esto:

self ? Entonces, ¿qué pasa con ese parámetro auto para todos los métodos del cliente? ¿Qué es? ¡Por qué, es la instancia, por supuesto! Dicho de otra manera, un método como el retiro define las instrucciones para retirar dinero de la cuenta de algún cliente abstracto. Al llamar a jeff.withdraw (100.0), esas instrucciones se utilizarán en la instancia de jeff.

Entonces, cuando decimos que se va a retirar (auto, cantidad): “aquí decimos cómo se retira dinero de un objeto del Cliente (al que llamaremos yo) y una cifra en dólares (a la que llamaremos monto). es la instancia del Cliente que se está solicitando la retirada. Tampoco estoy haciendo analogías. jeff.withdraw (100.0) es solo una abreviatura para Customer.withdraw (jeff, 100.0), que es perfectamente válido (si no se ve a menudo) código.

El yo inicial puede tener sentido para otros métodos, pero ¿qué pasa con el inic ? Cuando llamamos a init , estamos en el proceso de crear un objeto, entonces, ¿cómo puede haber un yo? Python nos permite extender el patrón propio cuando los objetos también se construyen, aunque no encaja exactamente. Solo imagine que jeff = Cliente (‘Jeff Knupp’, 1000.0) es lo mismo que llamar a jeff = Cliente (jeff, ‘Jeff Knupp’, 1000.0); El jeff que se pasa también se hace el resultado.

Esta es la razón por la que cuando llamamos a init , inicializamos objetos diciendo cosas como self.name = name. Recuerda, dado que el yo es la instancia, esto es equivalente a decir jeff.name = name, que es lo mismo que jeff.name = ‘Jeff Knupp. De manera similar, self.balance = balance es lo mismo que jeff.balance = 1000.0. Después de estas dos líneas, consideramos que el objeto Cliente está “inicializado” y listo para usar.

Ten cuidado con lo que __init__

Una vez que ha finalizado init , la persona que llama puede asumir correctamente que el objeto está listo para usar. Es decir, después de que jeff = Cliente (‘Jeff Knupp’, 1000.0), podemos comenzar a hacer depósitos y retirar llamadas en jeff; jeff es un objeto completamente inicializado.