PROGRAMACION ORIENTADA
A OBJETOS CON Python
Enlace a las guías
metodológicas
Un objeto
es un conjunto de datos y acciones que es
conveniente percibir como un todo.
Objetos del mundo real:
Lluvia de ideas
Cada uno de estos objetos almacena la
información necesaria sobre sí mismo y
conoce cómo realizar algunas acciones.
¡Conejo,
corre!
Lluvia de ideas
En el idioma español:
En el lenguaje de
programación: .
Conejo corre(
)
Propiedades y métodos del objeto
Cada objeto tiene propiedades y es controlado por métodos.
Propiedades Métodos
rabbit.speed = 50 rabbit.run()
turtle.speed = 1 turtle.walk()
fish.speed = 30 fish.swim()
Lluvia de ideas
Propiedades y métodos del objeto
Cada objeto tiene propiedades y es controlado por métodos.
Propiedades Métodos
rabbit.speed = 50 rabbit.run()
turtle.speed = 1 turtle.walk()
fish.speed = 30 fish.swim()
Lluvia de ideas
Variable colocada dentro del Función colocada
objeto. dentro del objeto.
Propiedades y métodos de acceso
El punto es la elección entre lo que recuerda el objeto y lo que
puede hacer.
object.method()
object.property
Lluvia de ideas
Programación Orientada a Objetos
Antes de nada, empecemos con una introducción básica a la
Programación Orientada a Objetos POO o OOP en inglés. Se trata de
un paradigma de programación introducido en los años 1970s, pero
que no se hizo popular hasta años más tarde.
Este modo o paradigma de programación nos permite organizar el
código de una manera que se asemeja bastante a como pensamos
Lluvia de ideas
en la vida real, utilizando las famosas clases. Estas nos permiten
agrupar un conjunto de variables y funciones que veremos a
continuación.
Cosas de lo más cotidianas como un perro o un coche pueden ser
representadas con clases. Estas clases tienen diferentes
características, que en el caso del perro podrían ser la edad, el
nombre o la raza. Llamaremos a estas características, atributos.
Programación Orientada a Objetos
Por otro lado, las clases tienen un conjunto de funcionalidades o
cosas que pueden hacer.
En el caso del perro podría ser andar o ladrar. Llamaremos a estas
funcionalidades métodos.
Por último, pueden existir diferentes tipos de perro. Podemos tener
Lluvia de ideas
uno que se llama Toby o el del vecino que se llama Laika.
Llamaremos a estos diferentes tipos de perro objetos. Es decir, el
concepto abstracto de perro es la clase, pero Toby o cualquier otro
perro particular será el objeto.
Programación Orientada a Objetos
La programación orientada a objetos está basada en 6 principios o
pilares básicos:
Herencia
Cohesión
Abstracción
Lluvia de ideas
Polimorfismo
Acoplamiento
Encapsulamiento
Programación Orientada a Objetos
Motivación
Una vez explicada la programación orientada a objetos puede
parecer bastante lógica, pero no es algo que haya existido siempre,
y de hecho hay muchos lenguajes de programación que no la
soportan.
Lluvia de ideas
En parte surgió debido a la creciente complejidad a la que los
programadores se iban enfrentando conforme pasaban los años. En
el mundo de la programación hay gran cantidad de aplicaciones que
realizan tareas muy similares y es importante identificar los
patrones que nos permiten no reinventar la rueda. La programación
orientada a objetos intentaba resolver esto.
Programación Orientada a Objetos
Motivación
Las funciones resultaron muy útiles, pero no eran capaces de
satisfacer todas las necesidades de los programadores. Uno de los
problemas de las funciones es que sólo realizan unas operaciones
con unos datos de entrada para entregar una salida, pero no les
importa demasiado conservar esos datos o mantener algún tipo de
estado. Salvo que se devuelva un valor en la llamada a la función o
Lluvia de ideas
se usen variables globales, todo lo que pasa dentro de la función
queda olvidado, y esto en muchos casos es un problema.
Programación Orientada a Objetos
Motivación
Imaginemos que tenemos un juego con naves espaciales
moviéndose por la pantalla. Cada nave tendrá una posición (x,y) y
otros parámetros como el tipo de nave, su color o tamaño. Sin hacer
uso de clases y POO, tendremos que tener una variable para cada
dato que queremos almacenar: coordenadas, color, tamaño, tipo. El
problema viene si tenemos 10 naves, ya que nos podríamos juntar
Lluvia de ideas
con un número muy elevado de variables. Todo un desastre.
En el mundo de la programación existen tareas muy similares al
ejemplo con las naves, y en respuesta a ello surgió la programación
orientada a objetos. Una herramienta perfecta que permite resolver
cierto tipo de problemas de una forma mucho más sencilla, con
menos código y más organizado. Agrupa bajo una clase un conjunto
de variables y funciones, que pueden ser reutilizadas con
características particulares creando objetos.
Programación Orientada a Objetos
¿Por qué utilizamos la programación orientada a objetos en
Python?
La POO permite crear software seguro y fiable. Muchos marcos y
bibliotecas de Python utilizan este paradigma para construir su
código base. Algunos ejemplos son Django, Kivy, pandas, NumPy y
TensorFlow.
Lluvia de ideas
Veamos las principales ventajas de usar OOP en Python.
Programación Orientada a Objetos
Ventajas de la POO de Python
Las siguientes razones te harán optar por utilizar la programación
orientada a objetos en Python.
Todos los lenguajes de programación modernos utilizan la POO
Este paradigma es independiente del lenguaje. Si aprendes POO en
Python, podrás utilizarlo en lo siguiente:
Lluvia de ideas
Java
PHP (asegúrate de leer la comparación entre PHP y Python)
Ruby
Javascript
C#
Kotlin
Programación Orientada a Objetos
La POO te permite codificar más rápido
Codificar más rápido no significa escribir menos líneas de código.
Significa que puedes implementar más funciones en menos tiempo
sin comprometer la estabilidad de un proyecto.
La programación orientada a objetos te permite reutilizar el código
mediante la implementación de la abstracción. Este principio hace
que tu código sea más conciso y legible.
Lluvia de ideas
Como ya sabrás, los programadores pasan mucho más tiempo
leyendo código que escribiéndolo. Es la razón por la que la
legibilidad es siempre más importante que sacar características lo
más rápido posible.
DEFINIENDO CLASES,
ATRIBUTOS, METODOS
Enlace a las guías
metodológicas
Definiendo Clases
Vista ya la parte teórica, vamos a ver como podemos hacer uso de
la programación orientada a objetos en Python. Lo primero es crear
una clase, para ello usaremos el ejemplo de perro.
# Creando una clase vacía
class Perro:
pass
Lluvia de ideas
Se trata de una clase vacía y sin mucha utilidad práctica, pero es la
mínima clase que podemos crear. Nótese el uso del pass que no
hace realmente nada, pero daría un error si después de los : no
tenemos contenido.
Definiendo Clases
Ahora que tenemos la clase, podemos crear un objeto de la misma.
Podemos hacerlo como si de una variable normal se tratase. Nombre
de la variable igual a la clase con (). Dentro de los paréntesis irían
los parámetros de entrada si los hubiera.
# Creamos un objeto de la clase perro
mi_perro = Perro()
Lluvia de ideas
Definiendo Atributos
A continuación vamos a añadir algunos atributos a nuestra clase.
Antes de nada es importante distinguir que existen dos tipos de
atributos:
Atributos de instancia: Pertenecen a la instancia de la clase o
al objeto. Son atributos particulares de cada instancia, en
nuestro caso de cada perro.
Lluvia de ideas
Atributos de clase: Se trata de atributos que pertenecen a la
clase, por lo tanto serán comunes para todos los objetos.
Definiendo Atributos
Empecemos creando un par de atributos de instancia para nuestro
perro, el nombre y la raza. Para ello creamos un método __init__ que
será llamado automáticamente cuando creemos un objeto. Se trata
del constructor.
class Perro:
# El método __init__ es llamado al crear el objeto
def __init__(self, nombre, raza):
Lluvia de ideas
print(f"Creando perro {nombre}, {raza}")
# Atributos de instancia
self.nombre = nombre
self.raza = raza
Definiendo Atributos
Ahora que hemos definido el método init con dos parámetros de
entrada, podemos crear el objeto pasando el valor de los atributos.
Usando type() podemos ver como efectivamente el objeto es de la
clase Perro.
mi_perro = Perro("Toby", "Bulldog")
print(type(mi_perro))
# Creando perro Toby, Bulldog
Lluvia de ideas
# <class '__main__.Perro'>
De esta manera, todos los objetos que se creen de la clase perro
compartirán ese atributo de clase, ya que pertenecen a la misma.
Definiendo Métodos
En realidad cuando usamos __init__ anteriormente ya estábamos
definiendo un método, solo que uno especial. A continuación vamos
a ver como definir métodos que le den alguna funcionalidad
interesante a nuestra clase, siguiendo con el ejemplo de perro.
Vamos a codificar dos métodos, ladrar y caminar.
Lluvia de ideas
El primero no recibirá ningún parámetro y el segundo recibirá el
número de pasos que queremos andar.
Como hemos indicado anteriormente self hace referencia a la
instancia de la clase. Se puede definir un método con def y el
nombre, y entre () los parámetros de entrada que recibe, donde
siempre tendrá que estar self el primero.
Definiendo Métodos
class Perro: Por lo tanto si
# Atributo de clase creamos un objeto
especie = 'mamífero’ mi_perro, podremos
hacer uso de sus
# El método __init__ es llamado al crear el objetollamándolos
métodos
def __init__(self, nombre, raza): con . y el nombre del
print(f"Creando perro {nombre}, {raza}")
método. Como si de
una función se
Lluvia de ideas
# Atributos de instancia tratase, pueden
self.nombre = nombre recibir y devolver
self.raza = raza argumentos.
def ladra(self):
print("Guau")
def camina(self, pasos):
print(f"Caminando {pasos} pasos")
Módulo 5. Lección 4. POO. Clases
Lluvia de ideas:
Creando
clases
¿Cómo creamos nuestro propio objeto?
Necesitamos saber lo siguiente:
➔ ¿Qué tipo de objeto es? ¿Qué datos lo describen?
➔ ¿Qué puede hacer este objeto? ¿Qué acciones realiza?
Lluvia de
ideas
Veamos un ejemplo usando un objeto familiar
Para crear su propio objeto, necesitan
describir sus datos y acciones.
➢ tiene ruedas ➢ tiene faros
➢ tiene puertas
➢ puede conducir
➢ se enciende — es
Lluvia de
un auto
ideas
➢ las personas pueden
sentarse en él
➢ tiene espejos
Una clase
es un nombre común para muchos objetos;
en la programación es una descripción general de cómo
deben ser estructurados estos objetos.
ES un auto
Lluvia de
Un objeto Clase de objeto
ideas
Conocimientos sobre todos estos objetos
Una instancia de una clase
es un objeto creado según la descripción programada en
la clase.
Lluvia de
ideas
Una instancia de
una clase
Una clase
Una instancia de una clase
es un objeto creado según la descripción programada en
la clase.
instance = Class()
El objeto recibe todo lo que Describiendo la clase:
conoce la clase y lo que sabe
hacer.
Lluvia de
Creando
Propiedades un objeto Propiedades
ideas
Métodos Métodos
Un constructor
es un método que es llamado automáticamente cuando un
objeto es creado. Crea una instancia de la clase.
El constructor a menudo establece las propiedades del objeto que está
siendo creado.
Lluvia de
ideas
Creando una clase
class es el comando que crea una clase.
self es el objeto actual de la clase.
Nombre de ():
class clase
Datos
def
Propiedad
__init__(self, Datos
):
self. = name
Lluvia de
def print_info(self):
ideas
Propiedad
print('Información sobre el objeto:', self.
)
Nombre de
Instancia = clase ( Propiedad )
Creando una clase
class es el comando que crea una clase.
self es el objeto actual de la clase.
Nombre de
El comando con el cual
class
(): empieza la descripción de
clase
la clase.
Datos
def
Propiedad
__init__(self, Datos
):
self. = name
Lluvia de
def print_info(self):
ideas
Propiedad
print('Información sobre el objeto:', self.
)
Nombre de
Instancia = clase ( Propiedad )
Creando una clase
class es el comando que crea una clase.
self es el objeto actual de la clase.
Nombre de ():
class clase
Datos Un constructor
def con el proceso de
Propiedad
__init__(self, Datos
): creación de una
self. = name instancia de la clase.
Lluvia de
def print_info(self):
ideas
Propiedad
print('Información sobre el objeto:', self.
)
Nombre de
Instancia = clase ( Propiedad )
Creando una clase
class es el comando que crea una clase.
self es el objeto actual de la clase.
Nombre de ():
class clase
Datos
def
Propiedad
__init__(self, Datos
):
self. = name
Lluvia de
Método
def print_info(self): de clase
ideas
(¡puede
Propiedad
print('Información sobre el objeto:', self. ser
cualquier
) a!)
Nombre de
Instancia = clase ( Propiedad )
Creando una clase
class es el comando que crea una clase.
self es el objeto actual de la clase.
Nombre de ():
class clase
Datos
def
Propiedad
__init__(self, Datos
):
self. = name
Lluvia de
def print_info(self):
ideas
Propiedad
print('Información sobre el objeto:', self.
) Creando una instancia de la
Nombre de clase con la propiedad
Instancia = clase ( Propiedad ) especificada.
Misión de texto "El Caballero y el Dragón"
La esencia de la misión:
➔ El caballero va a la guarida del dragón para
luchar y obtener sus tesoros.
➔ En su camino a la guarida, aparecen ladrones.
El caballero puede evitarlos o pelear contra
ellos.
➔ El caballero obtiene experiencia por derrotar
un ladrón. Su armadura se vuelve más
resistente y su golpe más fuerte. Pero podría
morir en la pelea y no llegar al dragón.
Lluvia de
ideas
Misión de texto "El Caballero y el Dragón"
¿Qué vamos a hacer?
➔ Vamos a crear la clase Hero.
➔ Vamos a describir los campos de la clase
en el constructor.
➔ Vamos a definir los métodos de la clase.
➔ Vamos a crear instancias de la clase Hero:
el caballero, los ladrones y el dragón.
➔ Vamos a programar duelos entre las
instancias de la clase.
Lluvia de
ideas
La clase Hero
Vamos a programar la clase con los campos y métodos establecidos en el mapa
mental.
Nombre del
personaje
Nivel de salud
Campos de la
clase Clase de
(propiedades) armadura
Fuerza de golpe
La clase
Arma
Hero
Lluvia de
Información impresa sobre el
ideas
personaje
Métodos de clase
Golpear al enemigo
Clase hero: constructor y mostrando datos
Al crear una instancia de una clase, un personaje con las propiedades
especificadas debe ser creado.
Salud: 50
Richard
Armadura: 25
Arma: espada
Lluvia de
ideas
Fuerza de golpe:
20
class Hero():
def __init__(self, name, health, armor, power, weapon):
self.name = name
self.health = health #número
self.armor = armor #número
self.power = power #número
self.weapon = weapon #cadena
def print_info(self):
print('Saludar al héroe ->', self.name)
Lluvia de
print('Nivel de salud:', self.health)
#Continúen por su cuenta
ideas
knight = Hero('Richard', 50, 25, 20, 'espada')
knight.print_info()
Clase Hero: método strike()
Vamos a crear dos instancias de la clase y programar un héroe que golpee al otro.
Richard Helen
Salud: 50 Salud: 20
Arma: espada Arma: arco y
flecha
Armadura: 25 Armadura: 5
Fuerza de golpe: Fuerza de golpe: 5
20
Lluvia de
ideas
Clase Hero: método strike()
Vamos a crear dos instancias de la clase y programar un héroe que golpee al otro.
Richard Helen
Salud: 50 Salud: 5
Arma: espada Arma: arco y
flecha
Armadura: 25 Armadura: 0
Fuerza de golpe: Fuerza de golpe: 5
20
Lluvia de
¡Golpe!
ideas
Vamos a añadir un método a la clase para atacar al enemigo.
Primero, se realiza daño a la armadura y cuando no quede nada, a la salud.
Se especifica como parámetro el
def strike(self, enemy): objeto Hero que está siendo golpeado.
print(
'-> ¡GOLPE! ' + self.name + ' está atacando a ' + enemy.name +
' con una fuerza de golpe de ' + str(self.power) + ', usando una ' + self.weapon
+ '\n')
El daño es realizado a la
enemy.armor -= self.power armadura. Si no queda
if enemy.armor < 0: armadura, se obtiene el
resto de la salud.
enemy.health += enemy.armor
Lluvia de
enemy.armor = 0
ideas
print(
enemy.name + ' se tambalea.\nClase de armadura reducida a '
+ str(enemy.armor) + ', y su nivel de salud está hasta '
+ str(enemy.health) + '\n')
class Hero():
def __init__(self, name, health, armor, power,
weapon):Cuerpo de método
def Cuerpo de método
print_info(self):
defCuerpo de método
strike(self, enemy):
Lluvia de
ideas
knight = Hero('Richard', 50, 25, 20, 'espada')
knight.print_info()
rascal = Hero('Helen', 20, 5, 5, 'arco y flecha')
rascal.print_info()
TIPOS DE METODOS
Enlace a las guías
metodológicas
Métodos en Python: instancia, clase y
estáticos
En diapositivas anteriores hemo visto como se pueden crear métodos
con def dentro de una clase, pudiendo recibir parámetros como
entrada y modificar el estado (como los atributos) de la instancia.
Pues bien, haciendo uso de los decoradores, es posible crear
diferentes tipos de métodos:
Lluvia de ideas
Lo métodos de instancia “normales” que ya hemos visto como
metodo()
Métodos de clase usando el decorador @classmethod
Y métodos estáticos usando el decorador @staticmethod
Métodos en Python: instancia, clase y
estáticos
En la siguiente clase tenemos un ejemplo donde definimos los tres
tipos de métodos.
class Clase:
def metodo(self):
Lluvia de ideas
return 'Método normal', self
@classmethod
def metododeclase(cls):
return 'Método de clase', cls
@staticmethod
def metodoestatico():
return "Método estático"
Veamos su comportamiento en detalle uno por uno
METODOS DE INSTANCIA
Enlace a las guías
metodológicas
Métodos de Instancia
Los métodos de instancia son los métodos normales, de toda la vida,
que hemos visto anteriormente. Reciben como parámetro de entrada
self que hace referencia a la instancia que llama al método. También
pueden recibir otros argumentos como entrada.
Para saber más: El uso de "self" es totalmente arbitrario. Se trata de
una convención acordada por los usuarios de Python, usada para
Lluvia de ideas
referirse a la instancia que llama al método, pero podría ser cualquier
otro nombre. Lo mismo ocurre con "cls", que veremos a continuación.
class Clase:
def metodo(self, arg1, arg2):
return 'Método normal', self
Métodos de Instancia
Y como ya sabemos, una vez creado un objeto pueden ser llamados.
mi_clase = Clase()
mi_clase.metodo("a", "b")
# ('Método normal', <__main__.Clase at
0x10b9daa90>)
Lluvia de ideas
En vista a esto, los métodos de instancia:
Pueden acceder y modificar los atributos del objeto.
Pueden acceder a otros métodos.
Dado que desde el objeto self se puede acceder a la clase con
` self.class`, también pueden modificar el estado de
la clase
Módulo 5. Lección 2. POO. Eventos
Lluvia de ideas:
Misión
El Caballero y el
Dragón
Misión de juego "El Caballero y el
Dragón" El caballero inicia su viaje
Permitir que el astuto ladrón
El caballero se encuentra un Peter, armado con un
ladrón e inicia una pelea cuchillo, se encuentre al
caballero en su viaje.
no sí
¿El ladrón murió?
La clase de armadura del
caballero y la fuerza de golpe
son elevados
DERROTA El caballero encuentra al
dragón y empieza a luchar
Lluvia de
no ¿El dragón sí
ideas
está muerto?
DERROTA VICTORIA
Misión de juego "El Caballero y el
Dragón" El caballero inicia su viaje
El caballero se encuentra un
ladrón e inicia una pelea
no sí
¿El ladrón murió?
La clase de armadura del
caballero y la fuerza de golpe
Tal vez, si el son elevados
caballero se vuelve
más fuerte en la
DERROTA lucha con el dragón.
El caballero encuentra al
dragón y empieza a luchar
Lluvia de
no ¿El dragón sí
ideas
está muerto?
DERROTA VICTORIA
Paso 1 - guardar Hero como un
módulo
➔ Dejar solo la clase hero en el nivel.
Guardarlo como el módulo Hero.
➔ En el siguiente nivel, conecten el módulo
Hero, creen los personajes del
caballero, el ladrón y el dragón y
muestre información sobre ellos.
Lluvia de
ideas
Paso 1 - guardar Hero como un
módulo
➔ Dejar solo la clase hero en el nivel.
Guardarlo como el módulo Hero.
➔ En el siguiente nivel, conecten el módulo
Hero, creen los personajes del
caballero, el ladrón y el dragón y
muestre información sobre ellos.
from hero import Hero
Lluvia de
knight = Hero('Richard', 50, 25, 20, 'espada')
ideas
rascal = Hero('Peter', 20, 5, 5, 'cuchillo')
dragon = Hero('Dragón', 150, 50, 50, 'flama')
#completar ustedes la muestra de datos
Paso 2 - crear el método fight()
La esencia del método:
❖ Los participantes en la pelea se pegan entre sí (el método strike())
hasta que solo uno permanece vivo.
Lluvia de
ideas
¿Cómo programamos ese método?
¿Es posible llamar el método strike() en el método
fight()?
Añadiremos el método fight() a la clase
Hero
Vamos a usar el método strike() en el cuerpo.
Nombre del
personaje
Campos de la Nivel de salud
clase Clase de
(propiedades) armadura
Fuerza de golpe
La clase Arma
Hero
Información impresa sobre el
Lluvia de
personaje
ideas
Golpear al enemigo
Métodos de clase
Luchar con el enemigo
Añadiremos el método fight() a la clase
Hero
Vamos a usar el método strike() en el cuerpo.
def fight(self, enemy): Siempre y cuando el nivel
while self.health and enemy.health > 0: de salud de los oponentes
sea mayor que 0.
self.strike(enemy)
if enemy.health <= 0: Los personajes se
atacan entre sí en
print(enemy.name, 'ha caído en esta difícil
turnos.
batalla.\n')
Si el nivel de salud de
break
uno de ellos es menor
sleep(5) que 0, la batalla se
termina.
Lluvia de
enemy.strike(self)
ideas
if self.health <= 0:
Colocaremos pausas
print(self.name, 'ha caído en esta difícil para generar intrigas.
batalla.\n')
break
class Hero(): #módulo Hero
def __init__(self, name, health, armor, power,
weapon):Cuerpo de método
Cuerpo de método
def print_info(self):
Cuerpo de método
def strike(self, enemy):
Lluvia de
Cuerpo de método
ideas
def fight(self, enemy):
Vamos a programar la batalla entre el
caballero y el ladrón en el siguiente
nivel.
La parte principal del programa:
from hero import Hero
knight = Hero('Richard', 50, 25, 20, 'espada')
knight.print_info()
rascal = Hero('Peter', 20, 5, 5, 'cuchillo')
rascal.print_info()
sleep(5)
Lluvia de
knight.fight(rascal)
ideas
Paso 3 - mejorando el golpe y la
armadura
La esencia del método:
❖ Si el caballero sobrevive:
➢ la salud es restaurada a su valor inicial;
➢ la clase de armadura es duplicada;
➢ la fuerza del golpe es doblada.
Lluvia de
ideas
¿Cómo programamos restaurar la salud
y mejorar la armadura y el golpe?
Vamos a añadir a la parte principal del
programa
Si el caballero sobrevive.
if knight.health > 0:
Restauramos la salud,
knight.health = 100 elevamos la fuerza y
duplicamos la
knight.power *= 2
armadura.
knight.armor = 10 * 2
print( Notificamos al usuario
sobre esos cambios.
'\n' + knight.name +
'recuperó su fuerza y ganó más experiencia. Ahora la
fuerza de golpe es: ' + str(knight.power) + ', y la
Lluvia de
clase de armadura:' + str(knight.armor) + '\n')
ideas
Añadiendo al código para la pelea con
el dragón y formando la narración:
Lluvia de
ideas
Tareas:
➔ Mover la clase Hero a un módulo separado.
➔ Añadiremos el método fight() a la clase Hero.
➔ ¡Programar la misión!
◆ Programar el duelo entre el caballero y el ladrón.
Si el caballero gana, se eleva la clase de armadura y la fuerza.
◆ Programar el duelo entre el caballero y el dragón.
Lluvia de
ideas