EL LENGUAJE DE PROGRAMACIN
PYTHON
Programacin orientada a objetos
Programacin funcional
Objetos y Clases
Objetos
Creacin de clases
xx == X()
X()
print(x)
print(x)
La clase Point
self?
Se crea el objeto.
Inmediatamente a continuacin, como
hemos visto, se llama al inicializador
Herencia
Herencia simple
>>>
>>> class
class A(B):
A(B):
...
pass
...
pass
Caractersticas de la herencia
B es un caso general de A
Polimorfismo
No existen en Python
Existe una convencin de uso, por la cual
si un atributo o mtodo empieza con el
carcter subrayado, ha de entenderse
que:
Es de uso interno
Encapsulamiento
Polimorfismo
Delegacin de responsabilidades
super
class
class A(B):
A(B):
def
def f(self,
f(self, arg):
arg):
super(A,
super(A, self).f(arg)
self).f(arg)
...
...
Python 3.x
class
class A(B):
A(B):
def
def f(self,
f(self, arg):
arg):
super().f(arg)
super().f(arg)
Funciones auxiliares
isinstance(objeto, clase)
issubclass(objeto, clase)
Sobrecarga de operadores
Ejemplos/clases_03.py
class
class A:
A:
_Tabla
_Tabla
0:
0:
3:
3:
6:
6:
}}
== {{
'ninguno',
'ninguno', 1:
1:
'tres',
4:
'tres',
4:
'umm...
'umm... seis',
seis',
'uno',
2:
'uno',
2: 'dos',
'dos',
'cuatro',
'cuatro', 5:
5: 'cinco',
'cinco',
def
def __len__(self):
__len__(self):
return
return 77 ## por
por la
la cara
cara
def
def __getitem__(self,
__getitem__(self, index):
index):
if
if 00 <=
<= index
index << 7:
7:
return
return self._Tabla[index]
self._Tabla[index]
else:
else:
return
return 'Muchos'
'Muchos'
def
def __setitem__(self,
__setitem__(self, index,
index, value):
value):
pass
pass
v1
v1
v2
v2
v3
v3
==
==
==
Vector(2,
Vector(2, 3)
3)
Vector(-4,
Vector(-4, 2)
2)
suma_vector(v1,
suma_vector(v1, v2)
v2)
ejemplos/clases_04.p
y
class
class Vector:
Vector:
def
def __init__(self,
__init__(self, x,
x, y):
y):
self.x
self.x == xx
self.y
self.y == yy
def
def __str__(self):
__str__(self):
return
return 'Vector({},
'Vector({}, {})'.format(self.x,
{})'.format(self.x, self.y)
self.y)
def
def __add__(self,
__add__(self, other):
other):
return
return Vector(
Vector(
self.x
self.x ++ other.x,
other.x,
self.y
self.y ++ other.y
other.y
))
def
def __sub__(self,
__sub__(self, other):
other):
return
return Vector(
Vector(
self.x
self.x -- other.x,
other.x,
self.y
self.y -- other.y
other.y
))
Sobrecarga de operadores: +/
http://www.rafekettler.com/magicmethods.html
Excepciones
Tipos de excepciones
Segn el error
ZeroDivisionError, ValueError, etc...
Como capturar excepciones: try/except
try:
try:
a,
a, bb == 7,
7, 00
cc == aa // bb
except
except ZeroDivisionError:
ZeroDivisionError:
print("No
print("No puedo
puedo dividir
dividir por
por cero")
cero")
Tratamiento de excepciones
Argumento de la excepcin
Elevar excepciones
Derivadas de Exception
Jerarqua de excepciones
Finally
Liberacin de recursos
Operaciones de limpieza
ficheros: open/close
memoria: malloc/free
Ms claro
En vez de hacer esto:
try:
try:
ff == open('fichero.datos',
open('fichero.datos', 'r')
'r')
## proceso
proceso el
el fichero
fichero
nn == len(f.readlines())
len(f.readlines())
finally:
finally:
f.close()
f.close()
Hacemos esto:
with
with open('fichero.datos',
open('fichero.datos', 'r')
'r') as
as f:
f:
...
## proceso
...
proceso el
el fichero
fichero
...
nn == len(f.readlines())
...
len(f.readlines())
Iteradores
Ejemplo
>>>
>>> ss == 'abc'
'abc'
>>>
>>> it
it == iter(s)
iter(s)
>>>
>>> it
it
<iterator
<iterator object
object at
at 0x00A1DB50>
0x00A1DB50>
>>>
>>> it.next()
it.next()
'a'
'a'
>>>
>>> it.next()
it.next()
'b'
'b'
>>>
>>> it.next()
it.next()
'c'
'c'
>>>
>>> it.next()
it.next()
Traceback
Traceback (most
(most recent
recent call
call last):
last):
File
File "<stdin>",
"<stdin>", line
line 1,
1, in
in ??
it.next()
it.next()
StopIteration
StopIteration
Ejercicio
Solucin
class
class CuentaAtras:
CuentaAtras:
def
def __init__(self,
__init__(self, tope):
tope):
self.tope
self.tope == tope
tope
def
def __iter__(self):
__iter__(self):
self.counter
self.counter == self.tope
self.tope
return
return self
self
def
def next(self):
next(self): return
return self.__next__()
self.__next__() ## python
python 2.7
2.7
def
def __next__(self):
__next__(self):
result
result == self.counter
self.counter
self.counter
self.counter -=
-= 11
if
if result
result << 0:
0:
raise
raise StopIteration
StopIteration
return
return result
result
Generadores
def
def cuenta_atras(n):
cuenta_atras(n):
while
while nn >=
>= 0:
0:
yield
yield nn
nn -=
-= 11
for
for ii in
in cuenta_atras(5):
cuenta_atras(5): print(i)
print(i)
Ventajas
Ejemplos de generadores/iteradores
Ejemplo de combinaciones
De uno en uno:
De dos en dos:
De tres en tres:
A, B, C, D
De cuatro en cuatro:
ABCD
La Fiscalia Anticorrupcin
nos pide ayuda
Ajustar cuentas
Los ingresos
1910.00
4090.20
1945.45
Los pagos
1404.93
207.68
297.39
1816.42
153.56
1286.85
322.90
175.04
335.43
259.74
301.28
1384.43
Herramientas
ejemplos/facturacion_b.py
facturacion_b.py (1)
from
from decimal
decimal import
import Decimal
Decimal
import
import itertools
itertools
ingresos
ingresos == [[
Decimal('4090.20'),
Decimal('4090.20'),
Decimal('1910.00'),
Decimal('1910.00'),
Decimal('1945.45'),
Decimal('1945.45'),
]]
pagos
pagos == [[
Decimal('1404.93'),
Decimal('1404.93'), Decimal('207.68'),
Decimal('207.68'), Decimal('297.39'),
Decimal('297.39'),
Decimal('1816.42'),
Decimal('1816.42'), Decimal('153.56'),
Decimal('153.56'), Decimal('1286.85'),
Decimal('1286.85'),
Decimal('322.9'),
Decimal('322.9'), Decimal('175.04'),
Decimal('175.04'), Decimal('335.43'),
Decimal('335.43'),
Decimal('259.74'),
Decimal('301.28'),
Decimal('259.74'), Decimal('301.28'), Decimal('1384.43'),
Decimal('1384.43'),
]]
facturacion_b.py (2)
for
for ingreso
ingreso in
in ingresos:
ingresos:
solucion
solucion == None
None
for
for size
size in
in range(1,
range(1, len(pagos)+1):
len(pagos)+1):
## Probando
Probando combinaciones
combinaciones de
de size
size elementos
elementos
for
a_probar
in
itertools.combinations(pagos,
for a_probar in itertools.combinations(pagos, size):
size):
if
if sum(a_probar)
sum(a_probar) ==
== ingreso:
ingreso:
print('Encontrada
print('Encontrada una
una solucin:')
solucin:')
solucion
solucion == tuple(a_probar)
tuple(a_probar)
print(*['{0:f}'.format(d)
print(*['{0:f}'.format(d) for
for dd in
in
solucion],
solucion],
sep='
sep=' ++ ',
',
end='
end=' == ')
')
print(ingreso)
print(ingreso)
break
break
if
if solucion:
solucion:
for
for pago
pago in
in solucion:
solucion:
pagos.remove(pago)
pagos.remove(pago)
Solucin
1816.42 + 153.56
+ 1286.85 + 322.9
+ 175.04 + 335.43 = 4090.20
1404.93 + 207.68 + 297.39 = 1910.00
259.74 + 301.28 + 1384.43 = 1945.45
Programacin funcional
Funciones Lambda
lambda(x,y): x+y
filter
Ejemplo
>>>
>>>
...
...
...
...
>>>
>>>
...
...
...
...
35
35
70
70
105
105
140
140
175
175
>>>
>>>
def
def div57(x):
div57(x):
return
return xx %% 55 ==
== 00 and
and xx %% 77 ==
== 00
for
for ii in
in filter(div57,
filter(div57, range(1,
range(1, 201)):
201)):
print(i)
print(i)
map
def
def cube(x):
cube(x): return
return x*x*x
x*x*x
map(cube,
map(cube, range(1,
range(1, 11))
11))
8,
8, 27,
27, 64,
64, 125,
125, 216,
216, 343,
343, 512,
512, 729,
729, 1000]
1000]
map (2)
reduce
def
def suma(x,y):
suma(x,y): return
return x+y
x+y
reduce(suma,
reduce(suma, range(1,
range(1, 11))
11))
def
def suma(x,y):
suma(x,y): return
return x+y
x+y
reduce(suma,
reduce(suma, range(1,
range(1, 11))
11))
Suma(1,2) = 3
Suma(21,7) = 28
Suma(3,3) = 6
Suma(28,8) = 36
Suma(6,4) = 10
Suma(36,9) = 45
Suma(10,5) = 15
Suma(45,10) = 55
Suma(15,6) = 21
def
def suma(x,y):
suma(x,y): return
return x+y
x+y
reduce(suma,
reduce(suma, range(1,
range(1, 11))
11))
Compresin de listas
10 Nmeros cuadrados
10 Nmeros cuadrados
10 Nmeros cuadrados
Corchete [
Expresin
Clusula for
Cero, una o ms clusulas if
Corchete ]
Ejercicio
'hola'.endswith('a') True
Respuesta
[x
[x for
for xx in
in range(501)
range(501) if
if str(x**3).endswith('272')]
str(x**3).endswith('272')]
[238,
[238, 488]
488]
Expresiones generadoras
Ejemplo
>>>
>>> ss == [x**2
[x**2 for
for xx in
in range(11)]
range(11)]
>>>
>>> ss ## es
es una
una lista
lista
[0,
[0, 1,
1, 4,
4, 9,
9, 16,
16, 25,
25, 36,
36, 49,
49, 64,
64, 81,
81, 100]
100]
>>>
>>> ss == (x**2
(x**2 for
for xx in
in range(11))
range(11))
>>>
>>> ss ## es
es un
un generador
generador
<generator
<generator object
object <genexpr>
<genexpr> at
at 0xb74588ec>
0xb74588ec>
>>>
>>> s.next()
s.next()
00
>>>
>>> for
for ii in
in s:
s: print(i)
print(i)
...
...
11
44
[...]
[...]
81
81
100
100
>>>
>>>
Comprensin de diccionarios
Ejemplos
>>>
>>> dd == {x:x**2
{x:x**2 for
for xx in
in range(5)}
range(5)}
>>>
>>> dd
{1:
{1: 1,
1, 0:
0: 0,
0, 3:
3: 9,
9, 2:
2: 4,
4, 4:
4: 16}
16}
>>>
>>> dd == {x:x**2
{x:x**2 for
for xx in
in range(5)
range(5) if
if xx %% 22 ==
== 0}
0}
>>>
>>> dd
{0:
{0: 0,
0, 2:
2: 4,
4, 4:
4: 16}
16}
>>>
>>> print({i
print({i :: chr(65+i)
chr(65+i) for
for ii in
in range(4)})
range(4)})
{0
{0 :: 'A',
'A', 11 :: 'B',
'B', 22 :: 'C',
'C', 33 :: 'D'}
'D'}
>>>
>>>
Conprensin de conjuntos
Ejemplo
>>>
>>> ss == {'a',
{'a', 'b',
'b', 'c'}
'c'}
>>>
>>> ss
set(['a',
set(['a', 'c',
'c', 'b'])
'b'])
>>>
>>> ss == {str(x**2)
{str(x**2) for
for xx in
in
>>>
>>> type(s)
type(s)
<type
<type 'set'>
'set'>
>>>
>>> ss
set(['25',
set(['25', '16',
'16', '36',
'36', '1',
'1',
>>>
>>>
range(7)}
range(7)}
'0',
'0', '4',
'4', '9'])
'9'])
Decoradores
Suena raro...
Una funcin
puede devolver
otra funcin
def
def dame_una_funcion_incremento(inc):
dame_una_funcion_incremento(inc):
def
def funcion_a_retornar(x):
funcion_a_retornar(x):
return
return xx ++ inc
inc
return
return funcion_a_retornar
funcion_a_retornar
inc3
inc3 == dame_una_funcion_incremento(3)
dame_una_funcion_incremento(3)
inc3(6)
inc3(6)
inc47
inc47 == dame_una_funcion_incremento(47)
dame_una_funcion_incremento(47)
inc47(3)
inc47(3)
Qu es un decorador?
Ejemplo de situacin
def
def a():
a():
## cdigo
cdigo de
de aa
A esto:
def
def a():
a():
with
with open('/tmp/log.txt',
open('/tmp/log.txt', 'a')
'a') as
as log:
log:
log.write('Empieza
log.write('Empieza la
la funcin
funcin a\n')
a\n')
## codigo
codigo de
de aa
with
with open('/tmp/log.txt',
open('/tmp/log.txt', 'a')
'a') as
as log:
log:
log.write('Acaba
log.write('Acaba la
la funcin
funcin a\n')
a\n')
Pegas de la opcin A
Decorador logged
Cdigo de logged
def
def logged(func):
logged(func):
def
def inner(*
inner(* args,
args, **kwargs):
**kwargs):
print('Empieza
print('Empieza la
la funcin
funcin {}'.
{}'.
format(func.__name__))
format(func.__name__))
func(*args,
func(*args, **kwargs)
**kwargs)
print('Termina
print('Termina la
la funcin
funcin {}'.
{}'.
format(func.__name__))
format(func.__name__))
return
return inner
inner
b():
b(): print('Soy
print('Soy b()')
b()')
logged(b)
logged(b)
@logged
@logged
def
def c():
c(): print('Soy
print('Soy c()')
c()')
@logged
@logged
def
def d(msg):
d(msg):
print('Soy
print('Soy dd yy digo:
digo: {}'.format(msg))
{}'.format(msg))
a()
a()
b()
b()
c()
c()
d('Hola,
d('Hola, mundo')
mundo')
Aplicacin de decoradores
La forma ms cmoda de aplicar el
decorador es poner el smbolo @ y el
nombre del decorador antes de la definicin
de la funcin
La forma:
@logged
@logged
def
def c():
c(): print('Soy
print('Soy c()')
c()')
c():
c(): print('Soy
print('Soy c()')
c()')
logged(c)
logged(c)