Tengo problemas para comprender la inicialización de clases.
¿Qué sentido tienen y cómo sabemos qué incluir en ellos? ¿Escribir en clases requiere un tipo diferente de pensamiento en comparación con la creación de funciones (pensé que podría simplemente crear funciones y luego envolverlas en una clase para poder reutilizarlas?
He aquí un ejemplo:
class crawler:
# Initialize the crawler with the name of database
def __init__(self,dbname):
self.con=sqlite.connect(dbname)
def __del__(self):
self.con.close()
def dbcommit(self):
self.con.commit()
U otra muestra de código:
class bicluster:
def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
self.left=left
self.right=right
self.vec=vec
self.id=id
self.distance=distance
Hay tantas clases con las que __init__
me encuentro cuando trato de leer el código de otras personas, pero no entiendo la lógica para crearlas.
Respuestas:
Por lo que escribió, se está perdiendo una pieza fundamental de comprensión: la diferencia entre una clase y un objeto.
__init__
no inicializa una clase, inicializa una instancia de una clase o un objeto. Cada perro tiene color, pero los perros como clase no. Cada perro tiene cuatro patas o menos, pero la clase de perros no. La clase es un concepto de objeto. Cuando ves a Fido y Spot, reconoces su similitud, su condición de perro. Esa es la clase.Cuando tu dices
Estás diciendo, Fido es un perro marrón con 4 patas, mientras que Spot es un poco lisiado y es mayormente amarillo. La
__init__
función se denomina constructor o inicializador y se llama automáticamente cuando crea una nueva instancia de una clase. Dentro de esa función, el objeto recién creado se asigna al parámetroself
. La notaciónself.legs
es un atributo llamadolegs
del objeto en la variableself
. Los atributos son una especie de variables similares, pero describen el estado de un objeto o acciones particulares (funciones) disponibles para el objeto.Sin embargo, tenga en cuenta que no se establece
colour
para el doghood en sí, es un concepto abstracto. Hay atributos que tienen sentido en las clases. Por ejemplo,population_size
es uno de esos: no tiene sentido contar el Fido porque Fido siempre es uno. Tiene sentido contar perros. Digamos que hay 200 millones de perros en el mundo. Es propiedad de la clase Dog. Fido no tiene nada que ver con el número 200 millones, ni Spot. Se llama "atributo de clase", a diferencia de "atributos de instancia" que soncolour
olegs
superiores.Ahora, a algo menos canino y más relacionado con la programación. Como escribo a continuación, la clase para agregar cosas no es sensata, ¿de qué es una clase? Las clases en Python se componen de colecciones de diferentes datos que se comportan de manera similar. La clase de perros consiste en Fido y Spot y 199999999998 otros animales similares a ellos, todos ellos haciendo pis en postes de luz. ¿En qué consiste la clase para agregar cosas? ¿En qué datos inherentes a ellos se diferencian? ¿Y qué acciones comparten?
Sin embargo, los números ... esos son temas más interesantes. Dime, enteros. Hay muchos, muchos más que perros. Sé que Python ya tiene números enteros, pero hagamos el tonto y los "implementemos" nuevamente (haciendo trampa y usando los números enteros de Python).
Entonces, los enteros son una clase. Tienen algunos datos (valor) y algunos comportamientos ("agrégame a este otro número"). Demostremos esto:
Esto es un poco frágil (asumimos
other
que será un MyInteger), pero lo ignoraremos ahora. En código real, no lo haríamos; lo probaríamos para asegurarnos, y tal vez incluso coaccionarlo ("¿no eres un número entero? ¡Caramba, tienes 10 nanosegundos para convertirte en uno! 9 ... 8 ...")Incluso podríamos definir fracciones. Las fracciones también saben cómo sumarse.
Hay incluso más fracciones que números enteros (en realidad no, pero las computadoras no lo saben). Hagamos dos:
En realidad, no declaras nada aquí. Los atributos son como un nuevo tipo de variable. Las variables normales solo tienen un valor. Digamos que escribe
colour = "grey"
. No puede tener otra variable nombradacolour
que"fuchsia"
no esté en el mismo lugar en el código.Las matrices resuelven eso hasta cierto punto. Si dice
colour = ["grey", "fuchsia"]
, ha apilado dos colores en la variable, pero los distingue por su posición (0 o 1, en este caso).Los atributos son variables que están vinculadas a un objeto. Al igual que con las matrices, podemos tener muchas
colour
variables, en diferentes perros . Entonces,fido.colour
es una variable, perospot.colour
es otra. El primero está vinculado al objeto dentro de la variablefido
; el segundospot
,. Ahora, cuando llameDog(4, "brown")
, othree.add(five)
, siempre habrá un parámetro invisible, que se asignará al extra que cuelga al principio de la lista de parámetros. Se llama convencionalmenteself
y obtendrá el valor del objeto delante del punto. Así, dentro del__init__
(constructor) del Perro ,self
estará lo que resulte ser el nuevo Perro; dentroMyInteger
deadd
,self
se vinculará al objeto en la variablethree
. Así,three.value
será la misma variable fuera deadd
, comoself.value
dentro deadd
.Si digo
the_mangy_one = fido
, comenzaré a referirme al objeto conocido comofido
con otro nombre. De ahora en adelante,fido.colour
es exactamente la misma variable quethe_mangy_one.colour
.Entonces, las cosas dentro del
__init__
. Puede pensar en ellos como anotando cosas en el certificado de nacimiento del Perro.colour
por sí misma es una variable aleatoria, podría contener cualquier cosa.fido.colour
oself.colour
es como un campo de formulario en la hoja de identidad del Perro; y__init__
el secretario lo está llenando por primera vez.¿Más claro?
EDITAR : Ampliando el comentario a continuación:
Te refieres a una lista de objetos , ¿no?
En primer lugar, en
fido
realidad no es un objeto. Es una variable, que actualmente contiene un objeto, al igual que cuando dicex = 5
,x
es una variable que actualmente contiene el número cinco. Si luego cambia de opinión, puede hacerlofido = Cat(4, "pleasing")
(siempre que haya creado una claseCat
) yfido
, a partir de ese momento, "contendrá" un objeto gato. Si lo hacefido = x
, contendrá el número cinco, y no un objeto animal en absoluto.Una clase por sí misma no conoce sus instancias a menos que usted escriba específicamente código para realizar un seguimiento de ellas. Por ejemplo:
Aquí,
census
es un atributo deCat
clase a nivel de clase.Tenga en cuenta que no obtendrá
[fluffy, sparky]
. Esos son solo nombres de variables. Si desea que los gatos mismos tengan nombres, debe crear un atributo separado para el nombre y luego anular el__str__
método para devolver este nombre. El propósito de este método (es decir, función ligada a la clase, comoadd
o__init__
) es describir cómo convertir el objeto en una cadena, como cuando lo imprime.fuente
Contribuir con mis 5 centavos a la explicación detallada de Amadan .
Donde las clases son una descripción "de un tipo" de forma abstracta. Los objetos son sus realizaciones: la cosa viva que respira. En el mundo orientado a objetos hay ideas principales que casi se pueden llamar la esencia de todo. Son:
Los objetos tienen una o más características (= Atributos) y comportamientos (= Métodos). El comportamiento depende principalmente de las características. Las clases definen lo que la conducta debería lograr de manera general, pero mientras la clase no se realice (instancia) como un objeto, sigue siendo un concepto abstracto de una posibilidad. Permítanme ilustrar con la ayuda de "herencia" y "polimorfismo".
Algunas características definen al ser humano. Pero cada nacionalidad difiere un poco. Así que los "tipos nacionales" son algo así como humanos con extras. Los "estadounidenses" son un tipo de "humanos" y heredan algunas características y comportamientos abstractos del tipo humano (clase base): eso es herencia. ¡Así que todos los humanos pueden reír y beber, por lo tanto, todas las clases para niños también pueden hacerlo! Herencia (2).
Pero debido a que todos son del mismo tipo (Tipo / clase base: Humanos), puede intercambiarlos a veces: vea el bucle for al final. Pero expondrán una característica individual, y ese es el polimorfismo (3).
Así que cada ser humano tiene una bebida favorita, pero todas las nacionalidades tienden a tomar un tipo especial de bebida. Si subclasifica una nacionalidad del tipo de Humanos, puede sobrescribir el comportamiento heredado como he demostrado anteriormente con el
drink()
Método. Pero eso todavía está en el nivel de clase y, debido a esto, sigue siendo una generalización.instancia la clase German y "cambié" una característica predeterminada al principio. (Pero si llamas a hans.drink ('Leche'), él todavía imprimiría "Necesito más cerveza", un error obvio ... o tal vez eso es lo que llamaría una función si fuera un Empleado de una Compañía más grande. ;-)! )
La característica de un tipo, por ejemplo, los alemanes (hans) generalmente se definen a través del constructor (en python :)
__init__
en el momento de la instanciación. Este es el punto en el que se define una clase para que se convierta en un objeto. Se podría decir que da vida a un concepto abstracto (clase) llenándolo de características individuales y convirtiéndolo en un objeto.Pero debido a que cada objeto es una instancia de una clase, comparten todos algunos tipos de características básicas y algún comportamiento. Esta es una gran ventaja del concepto orientado a objetos.
Para proteger las características de cada objeto, las encapsula, significa que intenta combinar el comportamiento y la característica y dificultar la manipulación desde fuera del objeto. Eso es encapsulación (1)
fuente
Es solo para inicializar las variables de la instancia.
Por ejemplo, cree una
crawler
instancia con un nombre de base de datos específico (de su ejemplo anterior).fuente
left=None
left se inicializará enNone
si al crearse elleft
parámetro no se especifica.left = foo
funcionaría, una vez. El objetivo de las clases es hacer algo sensato para todos los diferentescrawler
. Las clases no son funciones, ni algo que se pueda comparar con funciones (bueno, no hasta que estés mucho más avanzado y entres en programación funcional, pero eso te confundirá ahora). Lea mi respuesta para saber qué son realmente las clases: todavía no lo está obteniendo.Parece que necesita usar
__init__
en Python si desea inicializar correctamente los atributos mutables de sus instancias.Vea el siguiente ejemplo:
Esto es bastante diferente en Java, donde cada atributo se inicializa automáticamente con un nuevo valor:
produce una salida que intuitivamente esperamos:
Pero si declaras
attr
comostatic
, actuará como Python:fuente
Siguiendo con el ejemplo de su automóvil : cuando obtiene un automóvil, simplemente no obtiene un automóvil al azar, es decir, elige el color, la marca, el número de asientos, etc. Y algunas cosas también se "inicializan" sin que usted elija para ello, como número de ruedas o número de matrícula.
Entonces, en el
__init__
método, define los atributos de la instancia que está creando. Entonces, si queremos un automóvil Renault azul, para 2 personas, inicializaríamos o una instancia deCar
como:De esta forma, estamos creando una instancia de la
Car
clase. El__init__
es el que está manejando nuestros atributos específicos (comocolor
obrand
) y está generando los otros atributos, comoregistration_number
.__init__
métodofuente
Las clases son objetos con atributos (estado, característica) y métodos (funciones, capacidades) que son específicos para ese objeto (como el color blanco y los poderes de mosca, respectivamente, para un pato).
Cuando crea una instancia de una clase, puede darle algo de personalidad inicial (estado o carácter como el nombre y el color de su vestido para un recién nacido). Haces esto con
__init__
.Básicamente,
__init__
establece las características de la instancia automáticamente cuando llamainstance = MyClass(some_individual_traits)
.fuente
La
__init__
función está configurando todas las variables miembro de la clase. Entonces, una vez que se crea su bicluster, puede acceder al miembro y recuperar un valor:Consulte los documentos de Python para obtener más información. Querrá tomar un libro sobre conceptos de OO para continuar aprendiendo.
fuente
En el ejemplo anterior, usamos la especie como global, ya que siempre será la misma (se puede decir que es una especie de constante). cuando llame al
__init__
método__init__
, se iniciarán todas las variables internas (por ejemplo: raza, nombre).si imprime el ejemplo anterior llamando a continuación así
Eso significa que solo se inicializará durante la creación del objeto. por lo que cualquier cosa que desee declarar como constante lo convierte en global y cualquier cosa que cambie use
__init__
fuente