Programación orientada a objetos en python
domingo, 14 de agosto de 2022
En este gist alojado en github vemos un notebook sobre como se puede usar python con el paradigma orientado a objetos, incluye diagramas de clases con plant uml y ejemplos ejecutables de código, ademas de un enlace para que hagas tus pruebas en colab
Python orientado a objetos
Hola, El dia de hoy vamos a estar aprendiendo a programar en python usando jupyter notebook, e instalaremos python en nuestras maquinas, de momento no nos preocuparemos por entornos virtuales y nos apoyaremos en la instalación que tenga nuestro sistema operativo
El objetivo del dia de hoy es aprender sobre la creación de objetos en python
Instalación de python en windows
Colocar captura de como instale python en mi pc
Python en VS code
Visual studio code es un editor creado por Microsoft el cual permite el uso de extensiones para facilitar el desarrollo. Entre las extensiones que podemos instalar en VS Code están las extensiones de python y jupyter
Python: https://marketplace.visualstudio.com/items?itemName=ms-python.python Jupyter: https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter
Recomiendo la instalación de ambas incluyendo el paquete de extensiones de jupyter que trae los renderers para la salida de los notebooks https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-renderers
Si descargamos python desde microsoft store debemos adicionar la ruta donde se instala python al path, en mi caso es C:\Users\sergio.orozcot\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\Scripts
Para esta sesión nos apoyaremos en plant uml entonces por favor ejecutar la siguiente linea
!pip install iplantuml
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting iplantuml
Downloading IPlantUML-0.1.1.tar.gz (5.5 kB)
Collecting plantweb
Downloading plantweb-1.2.1-py3-none-any.whl (20 kB)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from plantweb->iplantuml) (1.15.0)
Requirement already satisfied: docutils in /usr/local/lib/python3.7/dist-packages (from plantweb->iplantuml) (0.17.1)
Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from plantweb->iplantuml) (2.23.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->plantweb->iplantuml) (2022.6.15)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->plantweb->iplantuml) (2.10)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->plantweb->iplantuml) (1.24.3)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->plantweb->iplantuml) (3.0.4)
Building wheels for collected packages: iplantuml
Building wheel for iplantuml (setup.py) ... [?25l[?25hdone
Created wheel for iplantuml: filename=IPlantUML-0.1.1-py2.py3-none-any.whl size=4910 sha256=976a41688f4de34923b643fe30cd57437ba613724d7e52558dc2ea135b53eef0
Stored in directory: /root/.cache/pip/wheels/cf/64/08/5bac65794ab011a60f7ef62413d3c430cf715345028f4b3914
Successfully built iplantuml
Installing collected packages: plantweb, iplantuml
Successfully installed iplantuml-0.1.1 plantweb-1.2.1
import iplantuml
Que la programación orientada a objetos
Es un paradigma de programación que parte del concepto de “objetos” como base, los cuales contienen información en forma de campos (a veces también referidos como atributos o propiedades) y código en forma de métodos.
%%plantuml
@startuml
Perro : ladrar()
@enduml
class Perro:
def ladrar(self):
print("guau guau!")
perro = Perro()
perro.ladrar()
guau guau!
Python es un lenguaje donde toca ser explicitos, y en cada metodo de clase es necesario agregar la referencia al objeto que por convención en python llamamos self
, lo que en algunos lenguajes de progamación llamariamos this
class Perro1:
def ladrar():
print("guau guau!")
perro = Perro1()
perro.ladrar()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
d:\intro python\poo_en_python_with_plant.ipynb Cell 10' in <cell line: 6>()
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000009?line=2'>3</a> print("guau guau!")
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000009?line=4'>5</a> perro = Perro1()
----> <a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000009?line=5'>6</a> perro.ladrar()
TypeError: Perro1.ladrar() takes 0 positional arguments but 1 was given
Metodos estaticos
Python soporta metodos estaticos. En python como tal para los utilitarios no necesitamos encapsularlo dentro de clases, ya que de por si las funciones son objetos pero si queremos lo podemos hacer.
class Util:
@staticmethod
def hacer_algo():
print("algo")
Util.hacer_algo()
algo
Metodos magicos
Son metodos especiales definidos por python y estan prefijados con __
class Specialstring:
def __len__(self):
return 25
normal_string = "Sergio"
print(len(normal_string))
string = Specialstring()
print(len(string))
6
25
Atributos de clases
Los atributos de clase en python normalmente se definen en el constructor __init__
y en dicho metodo se coloca el tipo de datos en caso de usar type hints
%%plantuml
@startuml
Persona : nombre
Persona : apellido
Persona : __str__(self)
Persona : __repr__(self)
@enduml
class Persona:
def __init__(self, nombre, apellido):
self.nombre = nombre
self.apellido = apellido
def __str__(self):
return "{} {}".format(self.nombre ,self.apellido)
def __repr__(self):
return "Persona('{}', '{}')".format(self.nombre, self.apellido)
sergio = Persona("Sergio", "Orozco")
print(sergio)
Sergio Orozco
Sobrecarga de operadores
La sobrecarga, en el contexto de la programación, se refiere a la capacidad de una función o de un operador de comportarse de diferentes maneras dependiendo de los parámetros que se pasan a la función o de los operandos sobre los que actúa el operador. Por ejemplo podemos definir la suma de 2 Puntos
%%plantuml
@startuml
Punto : x
Punto : y
Punto : __add__(self)
Punto : __str__(self)
Punto : __repr__(self)
@enduml
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Punto(1, 2)
p2 = Punto(3, 4)
print(p1+p2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
d:\intro python\poo-en-python.ipynb Cell 16' in <cell line: 9>()
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo-en-python.ipynb#ch0000015?line=5'>6</a> p1 = Punto(1, 2)
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo-en-python.ipynb#ch0000015?line=6'>7</a> p2 = Punto(3, 4)
----> <a href='vscode-notebook-cell:/d%3A/intro%20python/poo-en-python.ipynb#ch0000015?line=8'>9</a> print(p1+p2)
TypeError: unsupported operand type(s) for +: 'Punto' and 'Punto'
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Punto(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Punto(self.x - other.x, self.y - other.y)
def __repr__(self):
return "Punto({},{})".format(self.x, self.y)
p1 = Punto(5, 2)
p2 = Punto(3, 4)
print(p1 + p2)
print(p1 - p2)
Punto(8,6)
Punto(2,-2)
Sobrecarga del operador + en colecciones
En las colecciónes el operador + se usa para crear una nueva lista uniendo los elementos de ambas listas
(3,4)+(2,6)
(3, 4, 2, 6)
[1, 2] + [3, 4]
[1, 2, 3, 4]
{"nombre": "Sergio"} + {"apellido": "Orozco"}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
d:\intro python\poo-en-python.ipynb Cell 5' in <cell line: 1>()
----> <a href='vscode-notebook-cell:/d%3A/intro%20python/poo-en-python.ipynb#ch0000004?line=0'>1</a> {"nombre": "Sergio"} + {"apellido": "Orozco"}
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
Herencia y polimorfismo
La herencia es un mecanismo de relación entre clases donde decimos que una clase es un subtipo de otra, por ejemplo como decir que “Un gato es un Animal”
La herencia nos permite para heredar (tomar del padre): campos de datos, métodos de acceso de otra clase, ademas de poder añadir nuestros propios métodos y campos. Por lo tanto la herencia nos proporciona una manera de organizar el código para no tener que volver a repetir código.
%%plantuml
@startuml
AnimalTerrestre <|-- Gato
AnimalTerrestre <|-- Perro
AnimalTerrestre : caminar()
@enduml
class AnimalTerrestre:
def caminar(self):
print("Animal Caminando")
class Perro(AnimalTerrestre):
pass
class Gato(AnimalTerrestre):
def caminar(self):
print("Gato Caminando")
perro = Perro()
perro.caminar()
gato = Gato()
gato.caminar()
Animal Caminando
Gato Caminando
Herencia multiple
Python soporta la herencia multiple, lo cual nos permite reutilizar código de todas las clases de las cuales se herede
%%plantuml
@startuml
MiSuperClase1 <|-- MiClase
MiSuperClase2 <|-- MiClase
@enduml
class MiSuperClase1():
def metodo_1(self):
print("metodo_1 metodo llamado")
class MiSuperClase2():
def metodo_2(self):
print("metodo_2 metodo llamado")
# Clase que hereda las 2 clases anteriormente definidas
class MiClase(MiSuperClase1, MiSuperClase2):
def metodo_3(self):
print("metodo_3 metodo llamado")
# Se crea el objeto "c" y luego se llama al metodo_1 y metodo_2 heredados de las 2 primeras clases
c = MiClase()
c.metodo_1()
c.metodo_2()
El problema del diamante
Cuando tenemos herencia multiple puede suceder que heredemos de una clase la cual extiende de una base común, esto es lo que se llamaria el problema del diamante, y en python se resuelve escogiendo bien el orden en el cual heredamos los elementos
%%plantuml
@startuml
A <|-- B
A <|-- C
C <|-- D
B <|-- D
@enduml
class A:
def display(self):
print("I am the display of Class A")
class B(A):
def display(self):
print("I am the display of Class B")
class C(A):
def display(self):
print("I am the display of Class C")
class D(B, C):
pass
o = D()
o.display()
I am the display of Class B
Duck typing
Algo muy interesante de python es la filosofia de duck typing, si camina como pato, parece un pato, entonces es un pato
%%plantuml
@startuml
Bird : fly()
Airplane : fly()
Fish : swim()
@enduml
class Bird:
def fly(self):
print("fly with wings")
class Airplane:
def fly(self):
print("fly with fuel")
class Fish:
def swim(self):
print("fish swim in sea")
for obj in Bird(), Airplane(), Fish():
obj.fly()
fly with wings
fly with fuel
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
d:\intro python\poo_en_python_with_plant.ipynb Cell 39' in <cell line: 13>()
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000034?line=10'>11</a> print("fish swim in sea")
<a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000034?line=12'>13</a> for obj in Bird(), Airplane(), Fish():
---> <a href='vscode-notebook-cell:/d%3A/intro%20python/poo_en_python_with_plant.ipynb#ch0000034?line=13'>14</a> obj.fly()
AttributeError: 'Fish' object has no attribute 'fly'
Como importamos dependencias externas
No se pierdan la sesión 3 y la ultima de esta serie de tutoriales
Vamos a hablar de como creamos un proyecto trabajando con ficheros individuales mostrando como consumir un API en python usando requests
Conclusión
Python es un lenguaje bastante potente en el cual puedes realizar entre otras cosas automatizaciones de tareas repetitivas, o bien practicar tu lógica en programación, de hecho seria interesante si en este ultimo bloque escribes una funcion que te diga si una palabra es palidroma o no, (se lee igual si escribes los caracteres al reves), y un conversor de temperaturas
DataCamp es una plataforma que sirve para aprender a programar (está en ingles)echa https://www.datacamp.com/courses/intro-to-python-for-data-science
Refactoring guru es un sitio donde se pueden encontrar ejemplos de como implementar patrones de código en distintos lenguajes de programación https://refactoring.guru/es/design-patterns/python
Curso de python para principiantes de microsoft https://docs.microsoft.com/es-es/shows/intro-to-python-development/
Magic methods in python https://www.netjstech.com/2019/06/operator-overloading-in-python.html
Sobrecargada de operadores https://pharos.sh/sobrecargar-funciones-y-operadores-en-python/#:~:text=Sobrecarga%20del%20operador%20Python%20nos%20permite%20cambiar%20el,operadores%20de%20Python%20depende%20de%20las%20clases%20integradas.