Diseño y Programación Orientada a Objetos en Python.
Tags: python, oop
Published: 2022-05-22 18:46:26

Como aprendimos el año pasado, Python es un lenguaje multiparadigma. Esto quiere decir que admite más de un paradigma de programación para desarrollar aplicaciones.
La versatilidad de Python hace que se pueda adaptar a distintos entornos y plataformas. En lo que resta del año, vamos a desarrollar una aplicación web con el framework Django y Python orientado a objetos.

<u>
## Diseño y Desrrollo Orientado a Objetos en General.
</u>

Se puede pensar en los objetos como cápsulas de propiedades y procedimientos/métodos.
En POO, el razonamiento sobre los datos como objetos nos permite abstraer el código real y pensar más en los atributos de los datos y las operaciones alrededor de los datos. La POO ofrece las siguientes ventajas:

- Hace que el código sea reutilizable.
- Facilita el diseño de software, ya que puede modelarlo en términos de objetos del mundo real.
- Hace que sea más fácil de probar, depurar y mantener.
- Los datos están seguros debido a la abstracción y la ocultación de datos.

Las clases son un componente fundamental de la programación orientada a objetos. Se pueden comparar con los planos de un objeto, ya que definen qué propiedades y métodos/comportamientos debe tener un objeto. Por ejemplo, al construir una casa, debe seguir un plano que le diga cosas como cuántas habitaciones tiene la casa, dónde están ubicadas las habitaciones entre sí o cómo se distribuyen los circuitos eléctricos y de plomería. En POO, este plano de construcción sería la clase, mientras que la casa sería la instancia/objeto.

<u>
## Programación Orientada a Objetos en Python.
</u>

Todos los tipos de datos y estructuras de datos que ha encontrado hasta ahora, desde listas y cadenas hasta números enteros, funciones y otros, son objetos. Es por eso que cuando ejecutamos la función de tipo en cualquier objeto, tendrá el siguiente resultado:

```python
>>> type([1, 2, 3])
#output: <class'list'>
>>> type("foobar")
#output: <class'str'>
>>> type({"a": 1, "b": 2})
#output: <class'dict'> 
>>> def func(): return True
>>> type(func)
#output <class'function'>
```
Como ven, si usan la función 'type' en cada objeto, dicha función imprime que es una instancia de una clase específica. Las listas son instancias de la clase list, las cadenas son instancias de la clase str, los diccionarios son instancias de la clase dict, y así sucesivamente.

<u>
## Definir Clases en Python.
</u>

En este ejercicio, crearemos nuestra primera clase, llamada Persona. Los pasos son los siguientes:

- Declare la clase usando la palabra clave class de Python, seguida del nombre de clase Persona. En el bloque, tenemos la palabra clave pass de Python, que se usa como marcador de posición para el resto de la definición de nuestra clase:

```python
class Persona:
    pass
```

- Ejecute la función de tipo en esta clase que hemos creado; mostrará que nuestra clase es de tipo 'type':

```python
class Persona:
    pass

print(type(Person))

#output: <class 'type'>
```
Esto es un poco confuso, pero lo que significa es que, al igual que existen estructuras de datos de tipo list o dict, también, en cierto sentido, extendimos el lenguaje Python para incluir un nuevo tipo de estructura de datos llamada Persona. En Python, una clase y un tipo son sinónimos. Esta estructura Persona puede encapsular diferentes atributos y métodos que van a ser específicos para ese objeto.

<u>
## Inicializando el Objeto Persona
</u>

Tener un plano para construir algo es un gran primer paso. Sin embargo, los planos no son muy útiles si no puedes construir lo que describen. Instanciar un objeto de una clase es el acto de construir lo que describe el modelo/clase.
Por lo tanto, tenemos que instanciar la clase 'Persona' y lo vamos a hacer dos veces para realizar una comparación de estas instancias.
La primer instancia se va a llamar 'Roberto', mientras que la segunda será 'Adriana'. Es decir que, Roberto y Adriana, son instancias de la clase Persona. Sin embargo, cuando los comparamos, Pythoon nos dice que estos dos objetos no son lo mismo, y la consola nos devuelve 'False'. 

```python
class Persona:
    pass

Roberto = Persona()
Adriana = Persona()

print (Roberto is Adriana)
#output: False
```
Esto se debe a que un objeto no es el mismo que otro, aunque ambos sean instancias de una misma clase. Uno es totalmente independiente del otro.

La única forma de que dos instancias sean las mismas es que nosotros le asignemos el valor de una a la otra, por ejemplo:

```python
AdrianaClon = Adriana
#Output: True
```

<u>
## Agregando Atributos al Objeto
</u>

Un atributo es una característica específica de un objeto. Son variables solamente aplicables a la instancia que estamos utilizando.
En Python, podemos agregar atributos de forma dinámica, inicializando un objeto y colocando un punto seguido del nombre del atributo que queremos crear. Es importante aclarar que no es una buena práctica de programación y se desaconseja su uso.

```python
AdrianaClon.sobreNombre = "Adrianita"
```