Python [De Cero a Heroe] 2

Iniciado por Andrey, Febrero 17, 2018, 10:27:15 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Febrero 17, 2018, 10:27:15 PM Ultima modificación: Febrero 27, 2018, 12:23:48 AM por Andrey

7 Clases & Objetos

Un 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:

Código: php
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

Código: php
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:

Código: php
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:

Código: php
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:

Código: php
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:

Código: php
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:

Código: php
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:

Código: php
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 ".

Código: php
tesla_model_s = vehiculo (4,'electrico', 5, 250)
tesla_model_s.make_noise ()
#VRUUUUUUM



8 Encapsulación: ocultar información

La 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:

Código: php
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.

Código: php
an = persona ('AN')
print(an.primer_nombre)


Dentro de la clase:

Código: php
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".

Código: php
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":

Código: php
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:

Código: php
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":

Código: php
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:

Código: php
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:

Código: php
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" No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
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:

Código: php
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

Código: php
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 ( _).

Código: php
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:

Código: php
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:

Código: php
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ísticas

Ciertos 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.

Código: php
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ó:

Código: php
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.

Código: php
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:

Código: php
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í: "No tienes permitido ver los links. Registrarse o Entrar a mi cuenta".

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. "No tienes permitido ver los links. Registrarse o Entrar a mi cuenta".





Python de Cero a Heroe [ 1 ]
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta




Cualquier error favor de comentarlo o comunicarmelo, tambien estoy aprendiendo y soy humano. xd.

Andrey...


"Es un mundo brutal y peligroso el que hay allá afuera... Pero encontré mi camino. El caos es mi hogar, y me aseguraré de que no escapes de el"...

"Solo se necesita una excusa para cambiar el mundo"