Taller de PD
Taller de PD
Taller de PD
DISTRIBUIDA en Python
Introducción a programación orientada a
objetos (OOP) clases y objetos en Python
1 1
Taller de Programacion Distribuida Introducción a programación orientada a objetos
22 2
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Programación orientada a objetos (OOP)
• La Programación Orientada a Objetos (OOP) es un paradigma de
programación en el que los conceptos del mundo real relevantes para
nuestro problema se modelan a través de clases y objetos, y en programas
que incluyen una serie de interacciones entre estos objetos.
• A finales de los años 70 y comienzos de los 80 el paradigma de la
orientación a objetos se popularizó masivamente, primero con el lenguaje
Smalltalk (Alan Kay en el mítico laboratorio de Xerox, Palo Alto), después
con el C++ (Bjarne Stroustrup en los también míticos laboratorios Bell de
AT&T, 1983) y, por último, con el Java, uno de los lenguajes más populares
actualmente (creado por James Gosling en Sun Microsystems en 1995).
• El uso de la orientación a objetos se popularizó también durante las tareas
de análisis de sistemas, especialmente, a partir de la aparición en 1997 del
lenguaje unificado de modelización (UML), creado por James Rumbaugh,
Grady Booch e Ivar Jacobs.
33 3
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Programación orientada a objetos (OOP)
Clasificación
• Al utilizar orientación a objetos para describir los objetos que forman un
sistema nos damos cuenta de que hay objetos que son de un mismo tipo
y tienen una misma estructura y responsabilidades, es decir, atributos y
funciones.
• La clasificación es el mecanismo por el que simplificamos la descripción
de los objetos del sistema e identificamos aquellas clases de objetos que
comparten las mismas responsabilidades (atributos y funciones o
métodos).
• Por ejemplo, en un club de futbol una clase puede ser la plantilla de
jugadores (objetos) y otra clase sea las diferentes categorías: juvenil,
segunda plantilla y primera plantilla (objetos).
• Se denomina clase al grupo, e instancia al objeto.
44 4
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Programación orientada a objetos (OOP)
Clasificación - Ejemplo de una empresa*
* http://cv.uoc.edu/annotation/68cdc4848e7fd4149910ab359b7a710d/699675/PID_00232007/PID_00232007.html
55 5
Taller de Programcion Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Programación orientada a objetos (OOP)
Clasificación - Ejemplo de una empresa*
Las responsabilidades de los objetos de una clase, las podemos dividir en tres tipos:
• La información que conocen (los datos,
atributos o propiedades)
• Las tareas que pueden llevar a cabo (las
operaciones, métodos o funciones)
• Los objetos que conocen
(las asociaciones)
Un Empleado sabe cuál es su información
(nombre, teléfono, etc.), existe una serie
de tareas que puede llevar a cabo
(redactar una solicitud, aprobarla, etc.) y
está asociado con otras instancias (su
cargo y su departamento)
* http://cv.uoc.edu/annotation/68cdc4848e7fd4149910ab359b7a710d/699675/PID_00232007/PID_00232007.html
66 6
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Programación orientada a objetos (OOP)
Clases y objetos
Podemos resumir entonces:
Objeto: es una entidad que agrupa un estado o información (datos, atributos o
propiedades) y unas funcionalidades. En Python, el estado del objeto se define a
través de variables llamadas atributos, mientras que la funcionalidad se modela a
través de funciones a las que se les conoce con el nombre de métodos del objeto.
Clase: una plantilla genérica a partir de la cuál instanciar los objetos; plantilla que
es la que define qué atributos y métodos tendrán los objetos de esa clase.
Otra definición de clase puede ser: “Descriptor de un conjunto de objetos que
comparten los mismos atributos, métodos, relaciones y comportamiento”.
Ejemplo: Existen un conjunto de distintos objetos que llamamos coches tipo
turismo que tienen un conjunto de atributos comunes (marca, cilindrada, etc.) y
funcionalidades comunes y a este conjunto lo llamamos clase coche.
Otros conceptos de la OOP: encapsulamiento, herencia y polimorfismo.
77 7
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python
Conceptos previos: Espacios de nombres (namespace) y Ámbitos (Scope)
Las definiciones de clases en Python utilizan algunos trucos con los espacios de
nombres, que son interesantes para saber cómo funcionan los alcances (scope) y
espacios de nombres (namespace) en las clases.
Namespace: Un espacio de nombres (también llamado contexto) es un sistema de
nombres para hacer que los nombres sean únicos para evitar ambigüedades. Es una
relación de nombres a objetos.
Por ejemplo, la estructura de directorios de los sistemas de archivos. Se puede usar el
mismo nombre de archivo en diferentes directorios, a los archivos se puede acceder de
manera única a través de los nombres de ruta (pathname).
Un identificador o nombre definido en un espacio de nombres está asociado con ese
espacio de nombres. De esta manera, el mismo identificador puede definirse
independientemente en múltiples espacios de nombres. (Como los mismos nombres de
archivo en diferentes directorios).
88 8
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python
Conceptos previos: Espacios de nombres (namespace) y Ámbitos (Scope)
Namespace
Los espacios de nombres en Python se implementan como diccionarios: se definen
mediante una asignación de nombres (las claves del diccionario) a los objetos (los
valores).
Algunos espacios de nombres en Python:
• Nombres globales de un módulo
• Nombres locales en una invocación de función
o método
• Nombres incorporados (built-in): este espacio
de nombres contiene funciones built-in (por
ejemplo, abs (), int (), max(), …)
Por ejemplo, dos módulos diferentes pueden tener ambos definidos una función
maximizar sin confusión; los usuarios de los módulos deben usar el nombre del
módulo como prefijo: modulo1.maximizar, modulo2.maximizar.
99 9
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python
Conceptos previos: Espacios de nombres (namespace) y Ámbitos (Scope)
Namespace
Cuando se llama a una función, se crea un espacio de nombres local para esta función.
Este espacio de nombres se borra si la función finaliza (ej, return).
Scope (Ámbito)
Un ámbito (scope) es una región de un programa donde se puede acceder directamente
a un espacio de nombres, es decir, sin usar un prefijo de espacio de nombres.
En otras palabras: el ámbito de un nombre es el área de un programa donde este
nombre puede usarse sin ambigüedades, por ejemplo, dentro de una función.
1010 10
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python Espacios de nombres (namespace) y Ámbitos (Scope)
Ámbito local
Ámbito global Ámbito global
def myfunc():
x = 300 x = 300 x = 300
print(x)
def myfunc(): def myfunc():
myfunc() x = 200 global x
print(x) x = 200
300
def myfunc(): myfunc() myfunc()
x = 300
def mi_func_inter(): print(x) print(x)
print(x)
200 200
mi_func_inter()
300
myfunc()
300
1111 11
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python Espacios de nombres (namespace) y Ámbitos (Scope)
def scope_test(): Ejemplo que muestra cómo hacer
def do_local(): referencia a distintos ámbitos y espacios
spam = "local spam" de nombres, y cómo las declaraciones
def do_nonlocal():
nonlocal spam
global y nonlocal afectan la asignación de
spam = "nonlocal spam" variables
def do_global():
global spam
spam = "global spam"
Notar cómo la asignación local (default)
spam = "test spam" no cambió la vinculación de spam de
do_local() scope_test(). La asignación nonlocal
print("After local assignment:", spam)
cambió la vinculación de spam de
do_nonlocal()
print("After nonlocal assignment:", spam) scope_test(), y la asignación global
do_global() cambió la vinculación a nivel de módulo.
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam) After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
1212 12
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python. Siempre primera clase
En Python todo son clases. Guido van Rossum diseñó el lenguaje según el
principio todo de primera clase.
Guido escribió: Una de mis metas para Python era hacer que todos los objetos
fueran de “primera clase”. Con esto, quiso decir que quería todos los objetos
que pudieran usarse en el lenguaje (por ejemplo, enteros, strings, funciones,
clases, módulos, métodos, etc.) que puedan tener el mismo estado.
Es decir, “pueden asignarse a variables, colocarse en listas, almacenarse en
diccionarios, pasarse como argumentos, y así sucesivamente”. (Blog, The
History of Python, 27 de febrero de 2009)*
Esto significa que todo se trata de la misma manera, todo es una clase: las
funciones y los métodos son valores como listas, enteros o reales. Cada uno de
estos son instancias de sus clases correspondientes.
* http://python-history.blogspot.com/2009/02/
1313 13
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python
Ejemplos de instancias (objetos) de diferentes clases:
>>> x = 25
>>> type(x)
<class 'int'>
>>> y = 2.5
>>> type(y)
<class 'float'>
>>> def f(x):
return x+1
>>> type(f)
<class 'function'>
>>> import math
>>> type(math)
<class 'module'>
>>>
1414 14
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
OOP en Python
Una de las muchas clases integradas en Python es la clase list, que hemos utilizado en
muchos ejercicios y ejemplos. La clase list proporciona una gran cantidad de métodos
para crear listas, acceder y cambiar elementos, o eliminar elementos:
>>> x = [3, 6, 9]
>>> y = [45, "abc"]
>>> id(x)
2041851444808
>>> type(x)
<class 'list'>
>>> x.append(42)
>>> ultimo = y.pop()
>>> print(ultimo)
abc
• Las variables x e y del ejemplo denotan dos instancias de la clase list. En términos
simplificados, hemos dicho hasta ahora que "x e y son listas".
• Usaremos los términos objeto e instancia como sinónimos.
• Los objetos son la abstracción de Python para los datos. Cada objeto tiene una
identidad, un tipo y un valor.
1515 15
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Sintaxis de definición
Las clases introducen algo de sintaxis nueva
class NombreClase:
<sentencia-1>
...
<sentencia-N>
1616 16
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Crear Clases
Las clases soportan dos tipos de operaciones: hacer referencia a atributos e instanciación
Para hacer referencia a atributos se usa la sintaxis estándar de todas las referencias a
atributos en Python: objeto.nombre. Los nombres de atributo válidos son todos los
nombres que estaban en el espacio de nombres de la clase cuando ésta se creó. Por lo
tanto, si la definición de la clase es:
>>> MiClase.i
12345
>>> MiClase.__doc__
'Ejemplo simple de clase'
1717 17
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Crear objetos
La instanciación de clases usa la notación de funciones. Pensarlo como que el objeto
de clase es una función sin parámetros que devuelve una nueva instancia de la clase.
>>> x = MiClase()
>>> x.i
12345
>>> x.f()
'hola mundo'
La primera sentencia crea una nueva instancia de la clase y asigna este objeto a la
variable local x.
Los atributos de clase también pueden ser asignados, o sea que se pueden cambiar
el valor de MiClase.i mediante asignación.
>>> MiClase.i = 456
>>> x = MiClase()
>>> x.i
456
1818 18
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Crear objetos
La operación de instanciación crea un objeto vacío. Muchas clases necesitan crear
objetos en un estado inicial particular. Por lo tanto una clase puede definir un método
especial llamado __init__(), de esta forma:
def __init__(self): Lo insertamos en el
self.datos = [] """Ejemplo simple de clase"""
class MiClase:
"""Ejemplo simple de clase"""
i = 12345
def __init__(self):
self.datos = []
def f(self):
return 'hola mundo'
Cuando en una clase se define un método __init__(), la instanciación de la clase
invoca automáticamente a __init__() para la instancia recién creada. En el ejemplo:
>>> x = MiClase()
>>> x.datos
[]
1919 19
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Crear clases y objetos
El método __init__() puede también tener argumentos para mayor flexibilidad. En ese
caso, los argumentos que se pasen al operador de instanciación de la clase van a parar
al método __init__(). Por ejemplo:
class Complejo:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
>>> z = Complejo(3.0, -4.5)
>>> z.r, z.i
(3.0, -4.5)
2020 20
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Atributos y métodos de objetos
Atributos
Los objetos soportan dos tipos de referencia de atributos: atributos de datos y métodos.
Los atributos de datos de los objetos no necesitan ser declarados; tal como las variables
locales son creados la primera vez que se les asigna algo. Por ejemplo, si x es la instancia
de MiClase creada antes, se puede crear un atributo al objeto x de la forma:
>>> x.contador = 1
2121 21
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Atributos y métodos de objetos
Métodos
El otro tipo de referencia de atributo de instancia es un método. Un método es una
función que "pertenece" a un objeto. En el ejemplo MiClase, el método f():
... >>> x.f()
def f(self): 'hola mundo'
return 'hola mundo'
Pero no es necesario llamar al método justo en ese momento: en el siguiente ejemplo
x.f es un objeto método, y puede ser guardado y ser llamado más tarde.
>>> xf = x.f
>>> print(xf())
hola mundo
Hemos visto que un método difiere de una función solo en dos aspectos:
• Pertenece a una clase y se define dentro de una clase.
• El primer parámetro en la definición de un método tiene que ser una referencia a la
instancia, que llamó al método. Este parámetro generalmente se llama "self".
2222 22
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Métodos: De hecho, "self" no es una palabra clave de Python. ¡Es solo un nombre por
convención! Por lo tanto, los programadores de C ++ o Java son libres de llamarlo
"this", pero de esta manera se arriesgan a que otros tengan mayores dificultades para
comprender su código.
2323 23
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases
Variables de clases y de instancias
Las variables de instancia son datos únicos de cada instancia y las variables de las clases
son para atributos y métodos compartidos por todas las instancias de la clase:
class Perro:
>>> d = Perro('Roc')
>>> e = Perro('Luna')
>>> d.tipo # compartido por todos los perros
'canino'
>>> d.nombre # único de d
'Roc'
>>> e.nombre # único de e
'Luna'
2424 24
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases - Variables de clases y de instancias
Si hay objetos mutables (como listas) puede haber problemas cuando se comparte una
variable de la clase con todas las instancias. En el ejemplo de la clase perro, si en lugar
de tipo (string) tuviéramos la variable trucos (lista):
class Perro:
>>> d = Perro('Roc')
>>> e = Perro('Luna')
>>> d.agrega_truco('da vueltas')
>>> e.agrega_truco('salta la cuerda')
>>> d.trucos # resultado no deseado, compartido por todos los perros!
['da vueltas', 'salta la cuerda']
2525 25
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Primer vistazo a las clases - Variables de clases y de instancias
El diseño correcto de la clase debería usar una variable de instancia en lugar de clase:
class Perro:
""" Ejemplo de diseño de clase: perro"""
>>> d = Perro('Roc')
>>> e = Perro('Luna')
>>> d.agrega_truco('da vueltas')
>>> e.agrega_truco('salta la cuerda ')
>>> d.trucos
['da vueltas']
>>> e.trucos
['salta la cuerda']
2626 26
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python Ejemplo
Class Persona:
def __init__ (self, nombre, dni, edad): #Atributos: nombre,dni,edad
self.nombre = nombre
self.dni = dni
self.edad = edad
def iniciales(self): # Métodos
txt = ''
for caracter in self.nombre:
if caracter >= 'A' and caracter <= 'Z':
txt += caracter +'. '
return txt
def iniciales2(self):
lst = self.nombre.split()
txt = lst[0][0]+'.'+ lst[1][0]+'.'
return txt
def esMayorEdad(self):
return self.edad >= 18
#Objetos
Iniesta = Persona('Andrés Iniesta', '1234S', 35)
Sergio = Persona('Sergio Ramos', '5678C', 34 )
Saul = Persona('Saúl Ñiguez','7891W', 25)
2727 27
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Ocultación de información y encapsulamiento
Abstracción
En orientación a objetos, la abstracción es el mecanismo por el que decidimos qué
responsabilidades asociadas a una clase formarán parte de su definición.
Ocultación de información
Cada elemento (módulo o subsistema) del sistema contiene una cierta información que
"oculta" al resto de los módulos y les presenta una visión simplificada.
Encapsulamiento
La encapsulación se refiere a impedir el acceso a determinados métodos y atributos de
los objetos, estableciendo así, qué puede utilizarse desde fuera de la clase.
• La encapsulación se ve como la agrupación de datos con los métodos que operan en
esos datos.
• El ocultamiento de información es el principio de que cierta información interna o
datos están "ocultos", por lo que no se puede cambiar accidentalmente.
• La abstracción de datos está presente, si se utilizan tanto la ocultación de datos
como la encapsulación de datos. Esto significa que la abstracción de datos es el
término más amplio:
Abstracción de datos = Encapsulamiento + Ocultamiento de información
2828 28
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Ocultación de información y encapsulamiento
Encapsulamiento
El encapsulamiento nos permite ocultar información en otros objetos definiendo qué
atributos, operaciones y asociaciones de un objeto les serán visibles y cuáles estarán
ocultos.
Se denomina visibilidad de un atributo o método a la propiedad que define qué objetos
pueden verlo.
Los diferentes lenguajes de programación definen diferentes tipos de visibilidad, pero los
casos más típicos son:
• Visibilidad pública: cualquier objeto tiene acceso.
• Visibilidad privada: sólo los objetos de la misma clase tienen acceso.
• Visibilidad protegida: sólo los objetos de la misma clase o de alguna subclase tienen
acceso.
En Java (UML):
o Private (-): solo deben ser utilizados por el propietario (dentro de la definición de clase)
o Public (+) : los atributos públicos pueden y deben usarse libremente
o Protected (#): pueden usarse pero bajo ciertas condiciones
2929 29
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Ocultación de información y encapsulamiento
Encapsulamiento
Python usa un esquema de nombres especial para los atributos con el fin de controlar la
accesibilidad de los mismos.
Hasta ahora, hemos usado nombres de atributos, que se pueden usar libremente dentro
o fuera de una definición de clase, como hemos visto. Esto corresponde a los atributos
públicos, por supuesto.
Hay dos formas de restringir el acceso a los atributos de clase:
• Primero, podemos prefijar un nombre de atributo con un guión bajo "_". Esto marca
el atributo como protegido. Le dice a los usuarios de la clase que no usen este
atributo a menos que alguien escriba una subclase (herencia y subclases luego).
• En segundo lugar, podemos prefijar un nombre de atributo con dos guiones bajos
"__". El atributo ahora es inaccesible e invisible desde el exterior. No es posible leer
ni escribir en esos atributos, excepto dentro de la propia definición de clase
Identificador Tipo Significa
nombre público Se puede usar libremente desde fuera o dentro de la clase
_nombre protegido No debe usarse fuera de la clase
__nombre privado Atributo inaccesible e invisible
3030 30
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Encapsulamiento. Ejemplo en Python
Creamos el siguiente código y los guardamos como prueba_atributos.py
class A():
def __init__(self):
self.__priv = "Soy privado"
self._prot = "Estoy protegido"
self.pub = "Soy público"
Si queremos heredar los atributos y métodos y agregar otros nuevos se puede usar la
función super() como se verá en otro ejemplo.
3232 32
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Herencia Ejemplos
class Instrumento:
def __init__ (self, clase, nombre, precio):
self.clase = clase
self.nombre = nombre
self.precio = precio
def tocar(self):
print("Tocando música")
def romper(self):
print("¡Que has hecho! los", self.precio,"€ los vas a pagar")
"""
Heredar o extender/derivar una clase
"""
class bateria(Instrumento):
pass # Hereda atributos
class guitarra(Instrumento):
# Si está solo esto, sobreescribe los atributes de la clase principal
def __init__ (self, clase, nombre, precio, tipo):
super().__init__(clase, nombre, precio) # Hereda atributos
self.tipo = tipo
3333 33
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Polimorfismo
El polimorfismo es la capacidad de un objeto de presentarse con formas diferentes
(interfaces diferentes) según el contexto.
Las funciones o métodos polimórficos se pueden aplicar a argumentos de diferentes
tipos, y pueden comportarse de manera diferente dependiendo del tipo de argumentos
a los que se aplican. También podemos definir el mismo nombre de función con un
número variable de parámetros.
En Python, por ejemplo:
def f(x, y):
print("valores: ", x, y)
f(42, 43)
f(42, 43.7)
f(42.3, 43)
f([3,5,6],(3,5))
Podemos llamar a esta función con varios tipos de datos, como se demuestra en el
ejemplo. En lenguajes de programación tipados como Java o C ++, tendríamos que
sobrecargar (overloading) f() para implementar las diversas combinaciones de tipos.
Python es implícitamente polimórfico
3434 34
Taller de Programación Distribuida Introducción a programación orientada a objetos
Introducción a OOP, clases y objetos en Python
Misceláneos
Record y structure
A veces es útil tener un tipo de datos similar al registro (record) de Pascal o la estructura
(structure) de C o Matlab, que sirva para juntar algunos ítems con nombre. Una
definición de clase vacía funcionará perfectamente en este caso.
class Empleado:
pass
3535 35
Taller de Programación Distribuida Introducción a programación orientada a objetos
Comentarios finales
3636 36