0% encontró este documento útil (0 votos)
3 vistas16 páginas

Fundamentos de Programación en Python POO

El documento aborda los fundamentos de la programación orientada a objetos en Python, destacando su utilidad en proyectos grandes y complejos. Se explica la diferencia entre el enfoque procedimental y el orientado a objetos, así como conceptos clave como clases, objetos, herencia y encapsulamiento. Además, se presenta un ejemplo práctico de implementación de pilas utilizando ambos enfoques, mostrando las ventajas del enfoque orientado a objetos.

Cargado por

JMZ-MUSIC. LL
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas16 páginas

Fundamentos de Programación en Python POO

El documento aborda los fundamentos de la programación orientada a objetos en Python, destacando su utilidad en proyectos grandes y complejos. Se explica la diferencia entre el enfoque procedimental y el orientado a objetos, así como conceptos clave como clases, objetos, herencia y encapsulamiento. Además, se presenta un ejemplo práctico de implementación de pilas utilizando ambos enfoques, mostrando las ventajas del enfoque orientado a objetos.

Cargado por

JMZ-MUSIC. LL
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 16

Fundamentos de

Programación en Python:
Módulo 6
Los conceptos básicos del enfoque orientado a objetos
El enfoque orientado a objetos es
particularmente útil cuando se aplica a
proyectos grandes y complejos llevados a
cabo por grandes equipos formados por
muchos desarrolladores.

Este tipo de programación en un proyecto


facilita muchas tareas importantes, por
ejemplo, dividir el proyecto en partes
pequeñas e independientes y el desarrollo
independiente de diferentes elementos del
proyecto.

Python es una herramienta universal para


la programación procedimental y orientada a objetos.

Enfoque procedimental versus el enfoque orientado a


objetos
En el enfoque procedimental tenemos dos mundos separados: el de los
datos y el del código.
En el mundo de los datos se establecen las variables de diferentes tipos, y
en el mundo codificado se establecen las funciones.

¿Hay algún vinculo entre estos dos mundos? Por supuesto que sí. Las
funciones procesan los datos (información) pero no a la inversa.

¿Pero es esto completamente cierto?


¿Hay algunos tipos especiales de datos que pueden usar funciones? Sí.
Los métodos son funciones que se invocan desde dentro de los datos.
Aquí da inicio el enfoque de programación orientada a objetos.

Los datos y el código viven en un solo mundo (Encapsulados). Cada


mundo es una clase. Haciendo analogía a la cocina. Cada clase es una
receta que es capaz de producir platillos, es decir, objetos.

Cada objeto tiene propiedades o atributos.

Cada receta puede modificarse y


crear nuevas recetas (nuevas
clases) las nuevas recetas
pueden heredar propiedades y
métodos de la receta original.

Los objetos son


encarnaciones de las ideas
expresadas en clases, como un
pastel de queso en tu plato, es
una encarnación de la idea
expresada en una receta impresa
en un viejo libro de cocina.

Los datos mantienen


comunicación entre sí, intercambiando datos o activando sus métodos.

No existe un límite claro entre los datos y el código: viven como uno solo
dentro de los objetos.

Jerarquías de clase
La clase que nos concierne es como una categoría, como resultado de
similitudes definidas con precisión.

Intentaremos señalar algunas clases que son buenos ejemplos de este


concepto.

Todos los vehículos existentes (y los que aún no existen) están


relacionados por una sola característica importante: la capacidad de
moverse. Tenemos que mejorar la definición.
Consideremos las siguientes circunstancias: los vehículos son entidades
creadas artificialmente que se utilizan para el transporte, movidos por
fuerzas de la naturaleza y dirigidos (conducidos) por humanos.

La clase vehículos es muy amplia. Tenemos que definir clases


especializadas. Las clases especializadas son las subclases. La clase
vehículos será una superclase para todas ellas.

A estas alturas, probablemente puedas señalar algunas subclases


potenciales para la superclase Vehículos. Hay muchas clasificaciones
posibles. Elegimos subclases basadas en el medio ambiente y decimos
que hay (al menos) cuatro subclases:

 Vehículos Terrestres.
 Vehículos Acuáticos.
 Vehículos Aéreos.
 Vehículos Espaciales.

Los vehículos terrestres pueden dividirse aún más, según el método con el
que impactan el suelo. Entonces, podemos enumerar:

1. Vehículos de ruedas.
2. Vehículos oruga.
3. Aerodeslizadores.
Jerarquías de clase:
continuación
Otro ejemplo es la jerarquía del reino taxonómico de los animales.

Podemos decir que todos los animales (nuestra clase de nivel superior) se
puede dividir en cinco subclases:

1. Mamíferos.
2. Reptiles.
3. Pájaros.
4. Peces.
5. Anfibios.

Hemos identificado las siguientes subclases para la subclase mamíferos.

1. Mamíferos salvajes.
2. Mamíferos domesticados.

¿Qué es un objeto?
Una clase (entre otras definiciones) es un conjunto de objetos. Un objeto
es un ser perteneciente a una clase.
Un objeto es una encarnación de los requisitos, rasgos y cualidades
asignados a una clase específica.

Las clases forman una jerarquía. Esto puede significar que un objeto que
pertenece a una clase específica pertenece a todas las superclases al
mismo tiempo.

Cada subclase es más especializada (o más específica) que su


superclase. Por el contrario, cada superclase es más general (más
abstracta) que cualquiera de sus subclases.

¿Qué contiene un objeto?


La programación orientada a objetos supone que cada objeto existente
puede estar equipado con tres grupos de atributos:

1. Un objeto tiene un nombre que lo identifica. (Sustantivo)


2. Un objeto tiene un conjunto de propiedades individuales que lo hacen
original. (Adjetivo)
3. Un objeto tiene un conjunto de habilidades para realizar actividades
específicas, capaz de cambiar el objeto en sí, o algunos de los otros
objetos. (Verbo)

Ejemplos:

 Max es un gato grande que duerme todo el día.


Nombre del objeto = Max
Clase de inicio = Gato
Propiedad = Tamaño (grande)
Actividad = Dormir (todo el día)
 Un Cadillac rosa pasó rápidamente.
Nombre del objeto = Cadillac
Clase de inicio = Vehículo terrestre
Propiedad = Color (rosa)
Actividad = Pasar (rápidamente)
 Una ventana de una aplicación de agenda telefónica contiene un
menú de opciones.

Nombre del objeto = menú


Clase de inicio = ventana
Actividad = marcar número de teléfono

Herencia
Cualquier objeto vinculado a un nivel específico de una jerarquía de clases
hereda todos los rasgos (así como los requisitos y cualidades)
definidos dentro de cualquiera de las superclases.

Tu primera clase
La programación orientada a objetos es el arte de definir y expandir
clases.

La clase inicial será la superclase, de tal clase las subclases heredarán


sus propiedades y acciones así también podrán incluir propiedades y
acciones nuevas, propias de cada superclase.

El hecho de haber creado una super clase, no significa que un objeto se


creara automáticamente. Para ello, el programador tiene que crearlo con el
lenguaje en que se este laborando, en este caso Python.

Creación de una clase simple


class ClaseSimple:
pass

Creación de un objeto simple


Imagina que deseas crear un objeto (exactamente uno) de la clase
ClaseSimple.

Para hacer esto, debes asignar una variable para almacenar el objeto
recién creado de esa clase y crear un objeto al mismo tiempo.

Se hace de la siguiente manera:


miPrimerObjeto =
ClaseSimple()
Nota:

 El nombre de la clase intenta fingir que es una función, ¿puedes ver


esto? Lo discutiremos pronto.

 El objeto recién creado está equipado con todo lo que trae la clase;
Como esta clase está completamente vacía, el objeto también está
vacío.

El acto de crear un objeto de la clase seleccionada también se llama


instanciación (ya que el objeto se convierte en una instancia de la
clase).

¿Qué es una pila?


Una pila es una estructura desarrollada
para almacenar datos de una manera
muy específica.

El nombre alternativo para una pila (pero


solo en la terminología de TI) es UEPS
(LIFO son sus siglas en íngles). LIFO =
Last In – Firts Out.

Operaciones elementales: push (cuando


un nuevo elemento se coloca en la parte
superior) y pop (cuando un elemento
existente se retira de la parte superior).
La pila: el enfoque
pila =
procedimental
Utilización de una lista para almacenar
los valores de una pila.

def push(val): Función que inserta los valores de


pila.append(va manera que el ultimo que entra es el
primero que sale.
l)

def pop():

val = pila[- Función que elimina el ultimo valor


agregado a la pila y a su vez lo retorna.
1]
del pila[-1]
return val

La pila: el enfoque
procedimental frente al
enfoque orientado a objetos
La pila creada anteriormente es funciona, pero no tan optima como
pensamos, a medida que la utilices la pila tendrá varias desventajas, por
ejemplo:

1. La variable “pila []” es altamente vulnerable, es decir, se puede


modificar fácilmente ya que se puede llegar a confundir el nombre de
la variable, y fácilmente alguien podría hacer lo siguiente:
pila[0] = 9;

2. ¿Qué pasaría si requieres implementar varias pilas? Tendríamos que


crear otra pila, y probablemente otras funciones “push” y “pop”.

En conclusión habría mucho código redundante.

El enfoque orientado a objetos ofrece varias soluciones para los


problemas mencionados anteriormente.

1. Protección de los valores seleccionados contra el acceso no


autorizado, a esto se le conoce como “encapsulamiento”.

2. Obtención de una receta que replica los ingredientes esenciales para


cocinar una pila, es decir, tener una clase que implementa todos los
atributos y comportamientos necesarios de una pila. (Así nos
evitamos líneas de código iguales).

3. Creación de una subclase que herede los comportamientos y


atributos de la superclase y agregue unos nuevos.

La pila - el enfoque orientado


a objetos
1. Así es como comienza la pila en el enfoque orientado a objetos.

class Pila:

2. Ahora, esperemos dos cosas de la clase:


a. La clase tenga una propiedad que sea el almacenamiento de la
pila, es decir, cada objeto tendrá su propia lista.
b. La lista debe estar oculta de la vista de los usuarios de la clase.
¿Cómo se hace esto?

Debes agregar una instrucción específica. Las propiedades deben


agregarse a la clase manualmente.

¿Cómo garantizar que dicha actividad tiene lugar cada vez que se crea
una nueva pila?

Hay una manera simple de hacerlo - tienes que equipar a la clase con una
función específica:

1. Tiene que ser nombrada de forma estricta.


2. Se invoca implícitamente cuando se crea el nuevo objeto.

Tal función es llamada el constructor, ya que su propósito general es


construir un nuevo objeto.

El constructor sabe todo acerca del objeto y debe tener las inicializaciones
necesarias.

Ejemplo:

class Pila:
El nombre del constructor es siempre __init__
def __init__(self):
print("¡Hola!")
El parámetro se usa para representar el objeto recién
creado: puedes usar el parámetro para manipular el
objetoPila = Pila() objeto y enriquecerlo con las propiedades necesarias;

Parámetro obligatorio: self.

La salida del programa es: “¡Hola!”, el constructor ha sido invocado de


manera implícita y automáticamente.

class Pila: Modificación del estado del parámetro self (esta


def __init__(self): modificación se vera reflejada en el objeto recién creado).
self.listaPila = []
Se agrego una propiedad a “self” y esta permanecerá allí
hasta que termine la vida del objeto o la propiedad se elimine.
objetoPila = Pila()
print(len(objetoPila.listaPil
a))
Nota:

Notación punto -> forma general de acceder a las propiedades de un


objeto. (self.listaPila = [])

Establecimiento de una propiedad por primera vez a un objeto -> lo estas


creado; a partir de ese momento, el objeto tiene la propiedad.

Se accedió a la propiedad “listaPila” desde fuera de la clase, ¿se logró? Sí.

Esto no es lo que queremos de la pila. Nosotros queremos que listaPila


este escondida del mundo exterior. ¿Es eso posible?
Sí, y es simple, pero no muy intuitivo.

class Pila:
Se agregaron dos guiones bajos
def __init__(self): antes del nombre listaPila
self.__listaPila = []

objetoPila = Pila()
print(len(objetoPila.__listaPila
))
El cambio invalida el programa..

¿Por qué?
Cuando cualquier componente de la clase tiene un nombre que comienza
con dos guiones bajos (__), se vuelve privado - esto significa que solo se
puede acceder desde la clase.

Si se intenta acceder fuera de la clase, una excepción AttributeError


debe ser lanzada.

Pila en el enfoque orientado a objetos.


class Pila:

def __init__(self):
self.__listaPila = []

def push(self, val):


Las funciones parecen familiares, pero tienen más parámetros que sus
contrapartes procedimentales.

Ambas funciones tienen un parámetro llamado self en la primera posición


de la lista de parámetros. ¿Es necesario? Si, lo es.

Permite que el método acceda a entidades (propiedades y actividades


/ métodos) del objeto.

Python envía implícitamente el objeto como el primer argumento, es decir,


a self.

Esto significa que el método está obligado a tener al menos un


parámetro, que Python mismo utiliza - no tienes ninguna influencia
sobre él.

Si el método no ocupa ninguno parámetro aún así debes especificar “self”.

Ahora puedes hacer que más de una pila se comporte de la misma


manera. Cada pila tendrá su propia copia de datos privados, pero utilizará
el mismo conjunto de métodos.
objetoPila1 = Pila()
objetoPila2 = Pila()

objetoPila1.push(3)
objetoPila2.push(objetoPila1.pop())

print(objetoPila2.pop())
Existen dos pilas creadas a partir de la misma clase base. Trabajan
independientemente.

Ejemplo de la creación de 3 pilas independientes.


pequeñaPila = Pila()
otraPila = Pila()
graciosaPila = Pila()

pequeñaPila.push(1)
otraPila.push(pequeñaPila.pop() + 1)
graciosaPila.push(otraPila.pop() - 2)

print(graciosaPila.pop())
Vamos a agregar una nueva clase para manejar pilas.

La nueva clase debería poder evaluar la suma de todos los elementos


almacenados actualmente en la pila.

El primer paso es fácil: solo define una nueva subclase que apunte a la
clase que se usará como superclase.

class SumarPila(Pila):

Esto es lo que queremos de la nueva pila:

1. Queremos que el método push no solo inserte el valor en la pila, sino


que también sume el valor a la variable sum.
2. Queremos que la función pop no solo extraiga el valor de la pila, sino
que también reste el valor de la variable sum.

En primer lugar, agreguemos una nueva variable a la clase. Sera una


variable privada, al igual que la lista de pila. No queremos que nadie
manipule el valor de la variable sum.

self.__sum = 0

Python te obliga a invocar explícitamente el constructor de una


superclase. Omitir este punto tendrá efectos nocivos: el objeto se verá
privado de la lista __listaPila. Tal pila no funcionará correctamente.

Pila.__init__(self)
Ten en cuenta la sintaxis:

 Se especifica el nombre de la superclase (esta es la clase cuyo


constructor se desea ejecutar).

 Se pone un punto (.) después del nombre.

 Se especifica el nombre del constructor.

 Se debe señalar al objeto (la instancia de la clase) que debe ser


inicializado por el constructor; es por eso que se debe especificar el
argumento y utilizar la variable self aquí; recuerda: invocar
cualquier método (incluidos los constructores) desde fuera de la
clase nunca requiere colocar el argumento self en la lista de
argumentos

Nota: generalmente es una práctica recomendada invocar al constructor


de la superclase antes de cualquier otra inicialización que desees
realizar dentro de la subclase. Esta es la regla que hemos seguido en el
código.

Vamos a cambiar la funcionalidad de los métodos, no sus nombres.


Podemos decir con mayor precisión que la interfaz (la forma en que se
manejan los objetos) de la clase permanece igual al cambiar la
implementación al mismo tiempo.

Comencemos con la implementación de la función push. Esto es lo que


esperamos de la función:

 Agregar el valor a la variable __sum.

 Agregar el valor a la pila.

def push(self, val):


self.__sum += val
Pila.push(self, val)

Toma en cuenta la forma en que hemos invocado la implementación


anterior del método push (el disponible en la superclase):
 Tenemos que especificar el nombre de la superclase; esto es
necesario para indicar claramente la clase que contiene el método,
para evitar confundirlo con cualquier otra función del mismo nombre.

 Tenemos que especificar el objeto de destino y pasarlo como primer


argumento (no se agrega implícitamente a la invocación en este
contexto).

Se dice que el método push ha sido anulado - el mismo nombre que en la


superclase ahora representa una funcionalidad diferente.

Esta es la nueva función pop:

def pop(self):

val = Pila.pop(self)
self.__sum -= val
¿Cómoreturn
podemosvalmostrar el valor de __sum y que al mismo tiempo se
proteja de modificaciones?

Tenemos que definir un nuevo método. Lo nombraremos getSuma. Su


única tarea será devolver el valor de __sum.

def getSuma(self):
return self.__sum

Variables de instancia
En general, una clase puede equiparse con dos tipos diferentes de datos
para formar las propiedades de una clase.

Este tipo de propiedad existe solo cuando se crea explícitamente y se


agrega a un objeto. Como ya sabes, esto se puede hacer durante la
inicialización del objeto, realizada por el constructor.

Agregar una propiedad a un objeto se puede hacer en cualquier momento


de la vida del objeto. Y asi mismo eliminarla en cualquier punto.

Tal enfoque tiene algunas consecuencias importantes:


 Diferentes objetos de la misma clase pueden poseer diferentes
conjuntos de propiedades.

 Debe haber una manera de verificar con seguridad si un objeto


específico posee la propiedad que deseas utilizar (a menos que
quieras provocar una excepción, siempre vale la pena considerarlo).

 Cada objeto lleva su propio conjunto de propiedades - no


interfieren entre sí de ninguna manera.

También podría gustarte