(https://i.imgur.com/TpQmSHj.jpg)
7 Clases & ObjetosUn poco de teoría:
Los objetos son una representación de objetos del mundo real como automóviles, perros o bicicletas. Los objetos comparten dos características principales: datos y comportamiento.
Los automóviles tienen datos, como número de ruedas, número de puertas y capacidad de asientos. También exhiben comportamiento: pueden acelerar, detenerse, mostrar cuánto combustible queda, y muchas otras cosas.
Identificamos datos como atributos y comportamiento como métodos en programación orientada a objetos. De nuevo:
Datos → Atributos y Comportamiento → Métodos
Y una clase es el modelo a partir del cual se crean los objetos individuales. En el mundo real, a menudo encontramos muchos objetos del mismo tipo. Como autos. Todos de la misma marca y modelo (y todos tienen un motor, ruedas, puertas, etc.). Cada auto se construyó con el mismo conjunto de planos y tiene los mismos componentes.
Python, como un lenguaje de programación orientado a objetos, tiene estos conceptos: clase y objeto.
Una clase es un modelo, para sus objetos.
Entonces, nuevamente, una clase es solo un modelo, o una forma de definir atributos y comportamiento (como hablamos en la sección de teoría). Como ejemplo, una clase de vehículo tiene sus propios atributos que definen objetos. La cantidad de ruedas, el tipo de tanque, la capacidad de asientos y la velocidad máxima son atributos de un vehículo.
Con esto en mente, veamos la sintaxis de Python para las clases:
class vehiculo:
pass
Definimos clases con una declaración de clase, y eso es todo.
Los objetos son instancias de una clase. Creamos una instancia al nombrar la clase
carro = vehiculo()
print(carro)
# <__main__.vehiculo object at 0x000002605282C358>
Aquí en "carro" hay un objeto (o instancia) de la clase "Vehiculo".
Nuestra clase vehículo tiene cuatro atributos: número de ruedas, tipo de tanque, numero de asientos y velocidad máxima.
Establecemos todos estos atributos al crear un objeto de vehículo. Así que aquí, definimos nuestra clase para recibir datos cuando lo inicia:
class vehiculo:
def __init__(self, numero_de_ruedas, tipo_de_tanque, numero_de_asientos, velocidad_maxima):
self.numero_de_ruedas = numero_de_ruedas
self.tipo_de_tanque = tipo_de_tanque
self.numero_de_asientos = numero_de_asientos
self.velocidad_maxima = velocidad_maxima
Usamos el método "init". Lo llamamos un método constructor. Entonces cuando creamos el objeto del vehículo, podemos definir estos atributos. Imagine que tenemos el modelo S de Tesla, y queremos crear este tipo de objeto. Tiene cuatro ruedas, funciona con energía eléctrica, tiene espacio para cinco pasajeros y la velocidad máxima es de 250 km / hora. Vamos a crear este objeto:
tesla_model_s=vehiculo(4, 'electrico', 5, 250)
Cuatro ruedas + "tipo de tanque" eléctrico + cinco asientos + 250 km / hora de velocidad máxima.
Todos los atributos están establecidos. Pero, ¿cómo podemos acceder a los valores de estos atributos? Enviamos un mensaje al objeto preguntando sobre ellos. Lo llamamos un método. Es el comportamiento del objeto. Implementémoslo:
class vehiculo:
def __init__(self, numero_de_ruedas, tipo_de_tanque, numero_de_asientos, velocidad_maxima):
self.numero_de_ruedas = numero-de_ruedas
self.tipo_de_tanque = tipo_de_tanque
self.numero_de_asientos = numero_de_asientos
self.velocidad_maxima = velocidad_maxima
def numero_de_ruedas(self):
return self.numero_de_ruedas
def set_numero_de_ruedas(self, numero):
self.numero_de_ruedas=numero
Esta es una implementación de dos métodos: "numero_de_ruedas" y "set_ numero_de_ruedas". Lo llamamos "getter" & "setter". Porque el primero obtiene el valor del atributo, y el segundo establece un nuevo valor para el atributo.
En Python, podemos hacer eso usando "@property" ("decorators") para definir "getters" y "setters". Veámoslo con el código:
class vehiculo:
def __init__(self,numero_de_ruedas, tipo_de_tanque, numero_de_asientos, velocidad_maxima):
self.numero_de_ruedas = numero_de_ruedas
self.tipo_de_tanque = tipo_de_tanque
self.numero_de_asientos = numero_de_asientos
self.velocidad_maxima = velocidad_maxima
# @property
def numero_de_ruedas(self):
return self.numero_de_ruedas
# @numero_de_ruedas.setter
def set_numero_de_ruedas(self, numero):
self.numero_de_ruedas=numero
Y podemos usar estos métodos como atributos:
tesla_model_s=vehiculo(4, 'electrico', 5, 250)
print(tesla_model_s.numero_de_ruedas)
tesla_model_s.numero_de_ruedas=2
print(tesla_model_s.numero_de_ruedas)
#4
#2
Esto es ligeramente diferente a definir los métodos. Los métodos funcionan como atributos. Por ejemplo, cuando establecemos el nuevo número de ruedas, no aplicamos dos como parámetro, sino que establecemos el valor 2 en "numero_de_ruedas". Esta es una forma de escribir "getter" y "setter".
Pero también podemos usar métodos para otras cosas, como el método " make_noise ". Vamos a verlo:
class vehiculo:
def __init__(self,numero_de_ruedas, tipo_de_tanque, numero_de_asientos, velocidad_maxima):
self.numero_de_ruedas = numero_de_ruedas
self.tipo_de_tanque = tipo_de_tanque
self.numero_de_asientos = numero_de_asientos
self.velocidad_maxima = velocidad_maxima
def make_noise(self):
print('VRUUUUUUM')
Cuando llamamos a este método, simplemente devuelve una cadena " VRRRRUUUUM ".
tesla_model_s = vehiculo (4,'electrico', 5, 250)
tesla_model_s.make_noise ()
#VRUUUUUUM
8 Encapsulación: ocultar informaciónLa encapsulación es un mecanismo que restringe el acceso directo a los datos y métodos de los objetos. Pero, al mismo tiempo, facilita el funcionamiento de esos datos (métodos de objetos).
"La encapsulación se puede usar para ocultar los miembros de datos y la función de los miembros. Bajo esta definición, la encapsulación significa que la representación interna de un objeto generalmente se oculta a la vista fuera de la definición del objeto". - Wikipedia
Toda representación interna de un objeto está oculta desde el exterior. Solo el objeto puede interactuar con sus datos internos.
En primer lugar, tenemos que entender cómo "publico" y "no-publico" de instancia de variables y métodos de trabajo.
Variables de instancia pública
Para una clase de Python, podemos inicializar una variable de instancia pública dentro de nuestro método constructor. Veamos esto:
Dentro del método constructor:
class persona:
def __init__(self, primer_nombre):
self.primer_nombre=primer_nombre
Aquí aplicamos el valor "primer_nombre" como argumento a la variable de instancia pública.
an = persona ('AN')
print(an.primer_nombre)
Dentro de la clase:
class persona:
primer_nombre = 'AN'
Aquí, no necesitamos aplicar el "primer_nombre" como argumento y todos los objetos de instancia tendrán un "atributo de clase" inicializado con "an".
an = persona()
print(an.primer_nombre)
#AN
Ahora hemos aprendido que podemos usar "variables de instancia publica" y "atributos de clase". Otra cosa interesante sobre las parte publicas es que podemos administrar el valor de la variable. ¿Qué quiero decir con eso? Nuestra "objeto" puede gestionar el valor de la variable: "Get" y "Set" valores de las variables.
Teniendo en cuenta la clase "persona", queremos establecer otro valor para la variable "primer_nombre":
an = persona()
an.primer_nombre = 'Andrey'
print(an.primer_nombre)
#Andrey
Aquí vamos. Acabamos de establecer otro valor ("Andrey") a la variable "primer_nombre" de instancia y se actualizó el valor. Simple como eso. Como es una variable "publica", podemos hacer eso.
Variable de instancia no pública
Aquí no usamos el término "privado", ya que ningún atributo es realmente privado en Python (sin una cantidad de trabajo generalmente innecesaria). - PEP 8
Como las variables de instancia publica, podemos definir "variables de instancia no-publica" ambos dentro del método constructor o dentro de la clase. La diferencia de sintaxis es: para "variables de instancia no-publica", usa un guión bajo ( _) antes del nombre de "variable".
Las variables de instancia "privadas" a las que no se pueden acceder, excepto desde dentro de un objeto, no existen en Python. Sin embargo, hay una convención que es seguida por la mayoría del código de Python: un nombre prefijado con un guión bajo (por ejemplo _spam) debe tratarse como una parte no pública de la API (ya sea una función, un método o un miembro de datos)". - Python Software Foundation
Aquí hay un ejemplo:
class persona:
def __init__(self, primer_nombre, correo):
self.primer_nombre = primer_nombre
self._correo = correo
¿Viste la variable correo? Así es como definimos a la "variable no publica":
an=persona('AN', '[email protected]')
print (an._correo)
# [email protected]
Podemos acceder y actualizarlo. "Variables no públicas" deben tratarse como una parte no pública de la API.
Entonces usamos un método que nos permite hacerlo dentro de nuestra definición de clase. Implementemos dos métodos ("correo" y "actualizar_correo") para entenderlo:
class persona:
def __init__(self,primer_nombre, correo):
self.primer_nombre = primer_nombre
self._correo = correo
def actualizar_correo (self, nuevo_correo):
self._correo = nuevo_correo
def correo(self):
return self._correo
Ahora podemos actualizar y acceder a "variables no públicas" usando esos métodos. Veamos:
an=persona('AN', '[email protected]')
print (an._correo)
an._correo='[email protected]'
print(an._correo)
an.actualizar_correo('[email protected]')
print(an._correo)
# [email protected]
# [email protected]
# [email protected]
1 Iniciamos un nuevo objeto con "primer_nombre" AN y "correo"
[email protected]2 Imprimió el correo electrónico accediendo al "variable no-publica" con un método
3 Intenté establecer una nueva "correo" de nuestra clase
4 Necesitamos tratar "variable no-publica" como "no-publico"
5 Actualizado "variable no-publica" con nuestro método de instancia
6 Podemos actualizarlo dentro de nuestra clase con el método de ayuda
Método Público
Con "métodos públicos", también podemos usarlos fuera de nuestra clase:
class persona:
def __init__(self, primer_nombre, edad):
self.primer_nombre = primer_nombre
self._edad=edad
def ver_edad(self):
return self._edad
Vamos a probarlo
an=persona('AN', 23)
print (an.ver_edad())
# 23
Ahora podemos usarlo sin ningún problema.
Método no público
Pero con "métodos no publicos" nosotros no podemos hacerlo. Implementemos la misma clase "Persona", pero ahora con "_ver_edad" "método no-publico" usando un guión bajo ( _).
class persona:
def __init__(self, primer_nombre, edad):
self.primer_nombre = primer_nombre
self._edad = edad
def _ver_edad(self):
return self._edad
Y ahora, intentaremos llamar al "método no-publico" con nuestro objeto:
an = persona ('AN',23)
print(an._ver_edad()) # 23
Podemos acceder y actualizarlo. "Metodos no-publicos" deben tratarse como una parte no pública de la API.
Aquí hay un ejemplo de cómo podemos usarlo:
class persona:
def __init__(self, primer_nombre, edad):
self.primer_nombre=primer_nombre
self._edad=edad
def ver_edad(self):
return self._obtener_edad()
def _obtener_edad(self):
return self._edad
an=persona('AN',23)
print(an.ver_edad())
# 23
Aquí tenemos a "_get_edad" "método no-publico" y a "ver_edad" "método publico". El "ver_edad" puede ser utilizado por nuestro objeto (de la clase) y "_obtener_edad" única a utilizarse dentro de nuestra definición de clase (dentro de "ver_edad" del método). Pero nuevamente: como una cuestión de convención.
Resumen de encapsulación
Con la encapsulación podemos garantizar que la representación interna del objeto esté oculta desde el exterior.
9 Herencia: comportamientos y característicasCiertos objetos tienen algunas cosas en común: su comportamiento y características.
Por ejemplo, heredé algunas características y comportamientos de mi padre. Heredé sus ojos y cabello como características, y su impaciencia e introversión como comportamientos.
En la programación orientada a objetos, las clases pueden heredar características comunes (datos) y comportamiento (métodos) de otra clase.
Veamos otro ejemplo e impleméntalo en Python.
Imagina un auto. El número de ruedas, la capacidad de asientos y la velocidad máxima son todos atributos de un automóvil. Podemos decir que una clase carroElectrico hereda estos mismos atributos de la clase normal de coches.
class carro:
def __init__(self, numero_de_ruedas, asientos, velocidad_maxima):
self.numero_de_ruedas = numero_de_ruedas
self.asientos = asientos
self.velocidad_maxima = velocidad_maxima
Nuestra clase carro implementó:
mi_carro = carro(4, 5, 250)
print(mi_carro.numero_de_ruedas)
print(mi_carro.asientos)
print(mi_carro.velocidad_maxima)
# 4
# 5
# 250
Una vez iniciado, podemos usar todo lo creado "variables de instancia".
En Python, aplicamos "parent class" a "child class" como parámetro. La clase "carroElectrico" puede heredar de nuestra clase carro.
class carroElectrico:
def __init__(self, numero_de_ruedas, asientos, velocidad_maxima):
carro.__init__(self,numero_de_ruedas, asientos, velocidad_maxima)
Simple como eso. No necesitamos implementar ningún otro método, porque esta clase ya lo tiene (heredado de la clase carro). Vamos a probarlo:
mi_carro_electrico = carroElectrico(4, 5, 250)
print(mi_carro_electrico.numero_de_ruedas)
print(mi_carro_electrico.asientos)
print(mi_carro_electrico.velocidad_maxima)
Nota: Si Desea la versión en notebook la puede descargar aquí: "https://goo.gl/NbzbPc (https://goo.gl/NbzbPc)".
Extra: Lo siguiente es un diagrama titulado "Python en una imagen". Por cuestiones de calidad y comodidad dejo el link para verla en línea o descargarla. "https://goo.gl/RP4zPh (https://goo.gl/RP4zPh)".
(https://i.imgur.com/CecWRG8.png)
Python de Cero a Heroe [ 1 ]
https://underc0de.org/foro/python/python-de-cero-a-heroe-(-1-)/ (https://underc0de.org/foro/python/python-de-cero-a-heroe-(-1-)/)
Cualquier error favor de comentarlo o comunicarmelo, tambien estoy aprendiendo y soy humano. xd.
Andrey...