herency - Python__init__ y yo, ¿qué hacen?
subclass python (18)
Estoy aprendiendo el lenguaje de programació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.
Python
__init__
yself
¿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 programada.
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 programadores de Python te atañe y te ablande si lo cambias 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 usar " self ". 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ó auto en el método init, 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.
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 a.i
345
print MyClass.i
123
Los objetos de clase admiten dos tipos de operaciones: referencias de atributos y creación de instancias.
Las referencias de atributos utilizan la sintaxis 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 a __init__()
para la instancia de clase recién creada. Entonces, en este ejemplo, una nueva instancia inicializada se puede obtener de:
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)
x.r, x.i
Tomado de la documentation 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 :)
-
__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. -
self
representa ese objeto que heredará esas propiedades.
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 retirar 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 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 el objeto Cliente "inicializado" y listo para su uso.
Ten cuidado 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.
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.
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 en él, 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"
En breve:
-
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 variablea
para cada objeto. -
__init__
es lo que se llama como constructor en otros lenguajes OOP como C ++ / Java. La idea básica es que es un método especial al que se llama automáticamente cuando se crea un objeto de esa Clase.
En este código:
class A(object):
def __init__(self):
self.x = ''Hello''
def method_a(self, foo):
print self.x + '' '' + foo
... la variable self
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 (p. Ej., A(24, ''Hello'')
también se pasará como argumentos; en este caso, se genera una excepción, ya que el constructor no los está esperando.
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
Prueba este código. Espero que ayude a muchos programadores 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
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 pila y se descartarán cuando el método init salga del alcance. 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).
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
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 estableciendo 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 con la misma facilidad, 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 utilizar uno mismo porque otros pitones lo reconocerán más fácilmente.
__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.
# 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()