Professional Documents
Culture Documents
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
2 / 230
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
3 / 230
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
4 / 230
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
5 / 230
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
6 / 230
Introducci
on
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
7 / 230
Introducci
on
#! /usr/bin/env python
# encoding: UTF-8
3
4
class Perro(object):
5
6
7
8
9
10
11
12
def ladra(self):
print self.nombre, "dice Wooof!"
13
14
15
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
8 / 230
Introducci
on
No os limiteis a escuchar!
No suele ser divertido escuchar a nadie hablar durante
casi una hora. Participad, intervenid, criticad, opinad.
Si digo algo que no tiene ningun sentido, corregidme!
Transparencias y codigo fuente en:
http://github.com/vterron/PyConES-2014
Erratas, correcciones, enlaces, cualquier cosa!
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
9 / 230
Introducci
on
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
10 / 230
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
11 / 230
class Perro(object):
2
3
4
5
6
7
8
9
10
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
12 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
13 / 230
2
3
4
5
6
7
8
9
10
9 de noviembre de 2014
14 / 230
slots
9 de noviembre de 2014
15 / 230
class Spam(object):
pass
3
4
raise Spam()
Traceback (most recent call last):
File "./code/00/02-new-style-raise.py", line 4, in <module>
raise Spam()
TypeError: exceptions must be old-style classes or derived from
BaseException, not Spam
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
16 / 230
class Foo:
pass
3
4
raise Foo()
Traceback (most recent call last):
File "./code/00/03-old-style-raise.py", line 4, in <module>
raise Foo()
__main__.Foo: <__main__.Foo instance at 0x402b948c>
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
17 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
18 / 230
01. super()
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
19 / 230
01. super()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
20 / 230
01. super()
# encoding: UTF-8
2
3
4
5
6
class ListaLogger(list):
def append(self, x):
print "Intentando a~
nadir", x
self.append(x)
7
8
9
numeros = ListaLogger()
numeros.append(7)
Intentando
Intentando
Intentando
Intentando
Intentando
Intentando
Intentando
Intentando
a~
nadir
a~
nadir
a~
nadir
a~
nadir
a~
nadir
a~
nadir
a~
nadir
a~
nadir
Vctor Terr
on (IAA-CSIC)
7
7
7
7
7
7
7
7
9 de noviembre de 2014
21 / 230
01. super()
# encoding: UTF-8
2
3
4
5
6
class ListaLogger(list):
def append(self, x):
print "A~
nadiendo", x, "a la lista (ahora s
!)"
super(ListaLogger, self).append(x)
7
8
9
10
numeros = ListaLogger()
numeros.append(7)
print numeros
A~
nadiendo 7 a la lista (ahora s
!)
[7]
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
22 / 230
01. super()
class Punto(object):
def __init__(self, x, y):
self.x = x
self.y = y
5
6
7
8
9
class Circulo(Punto):
def __init__(self, x, y, radio):
super(Circulo, self).__init__(x, y)
self.radio = radio
10
11
12
13
14
c = Circulo(3, 4, 5.5)
print "x:", c.x
print "y:", c.y
print "r:", c.radio
x: 3
y: 4
r: 5.5
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
23 / 230
01. super()
class ListaLogger(list):
def append(self, x):
print("Esto tambi
en a~
nade", x)
super().append(x)
5
6
7
8
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
24 / 230
01. super()
9 de noviembre de 2014
25 / 230
01. super()
01. T-1000
1
# encoding: UTF-8
2
3
4
5
class Humano(object):
def ataca(self):
print "Pu~
netazo"
6
7
8
9
class Cyborg(Humano):
def ataca(self):
print "L
aser"
10
11
12
13
class Ninja(Humano):
def ataca(self):
print "Shuriken"
14
15
16
17
18
19
20
21
22
9 de noviembre de 2014
26 / 230
01. super()
01. T-1000
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
27 / 230
01. super()
01. T-1000
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
28 / 230
01. super()
01. T-1000
1
# encoding: UTF-8
2
3
4
5
class Humano(object):
def ataca(self):
print "Pu~
netazo"
6
7
8
class Cyborg(Humano):
pass
9
10
11
12
class Ninja(Humano):
def ataca(self):
print "Shuriken"
13
14
15
16
17
18
19
20
robot = T1000()
robot.ataca(5)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
29 / 230
01. super()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
30 / 230
01. super()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
31 / 230
01. super()
# encoding: UTF-8
2
3
4
5
class Humano(object):
def ataca(self):
print "Pu~
netazo"
6
7
8
9
class Cyborg(Humano):
def defiende(self):
print "Armadura"
10
11
12
13
class Ninja(Humano):
def ataca(self):
print "Shuriken"
14
15
16
17
18
19
20
robot = T1000()
robot.defiende()
robot.ataca()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
32 / 230
01. super()
init () methods
https://stackoverflow.com/q/576169/184363
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
33 / 230
01. super()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
34 / 230
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
35 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
36 / 230
01. Ejemplo:
1
init () y distancia()
import math
2
3
4
5
6
class Punto(object):
def __init__(self, x, y):
self.x = x
self.y = y
7
8
9
10
11
12
13
14
15
c1 = Punto(8, 1)
c2 = Punto(4, 7)
print c1.distancia(c2)
7.21110255093
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
37 / 230
class Punto(object):
def __init__(this, x, y):
this.x = x
this.y = y
5
6
7
8
9
class Circulo(Punto):
def __init__(this, x, y, radio):
super(Circulo, this).__init__(x, y)
this.radio = radio
10
11
12
13
14
c = Circulo(2, 7, 5)
print "x:", c.x
print "y:", c.y
print "r:", c.radio
x: 2
y: 7
r: 5
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
38 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
39 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
40 / 230
import math
2
3
4
5
6
class Punto(object):
def __init__(x, y):
self.x = x
self.y = y
7
8
9
10
11
def distancia(otro):
x_delta = self.x - otro.x
y_delta = self.y - otro.y
return math.sqrt(x_delta ** 2 + y_delta ** 2)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
41 / 230
class Punto(object):
def __init__(self, x, y):
self.x = x
self.y = y
5
6
p = Punto(1)
Traceback (most recent call last):
File "./code/02/23-self-error.py", line 6, in <module>
p = Punto(1)
TypeError: __init__() takes exactly 3 arguments (2 given)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
42 / 230
El Zen de Python
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
43 / 230
import math
2
3
4
5
6
class Punto(object):
def __init__(self, x, y):
self.x = x
self.y = y
8
9
10
11
12
13
14
15
c1 = Punto(4, 1.5)
c2 = Punto(3, 3.1)
print c1.distancia(c2) == Punto.distancia(c1, c2)
True
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
44 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
45 / 230
class C(object):
pass
3
4
5
6
7
C.init_x = init_x
8
9
10
11
c = C()
c.init_x(23)
print c.x
23
init x() esta definida fuera de la clase (es una funci
on), y como argumento
recibe la referencia al objeto cuyo atributo x es modificado. Basado en el
ejemplo de Guido van Rossum.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
46 / 230
9 de noviembre de 2014
47 / 230
Moraleja
Usamos self para acceder los atributos del objeto [*]
[*] Un metodo es un atributo ejecutable ver callable()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
48 / 230
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
50 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
51 / 230
03. Ejemplo
1
2
class T1000(object):
jefe = "Skynet"
3
4
5
robot1 = T1000()
robot2 = T1000()
6
7
8
print robot1.jefe
print robot2.jefe
Skynet
Skynet
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
52 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
53 / 230
class T1000(object):
jefe = "Skynet"
3
4
5
robot1 = T1000()
robot2 = T1000()
6
7
8
9
10
11
print robot1.jefe
print robot2.jefe
Skynet
James Cameron
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
54 / 230
class Constantes(object):
pi = 3.141592653589793
3
4
9 de noviembre de 2014
55 / 230
PI = 3.141592653589793
2
3
4
5
6
7
class Circulo(object):
def __init__(self, x, y, radio):
self.x = x
self.y = y
self.radio = radio
8
9
10
def area(self):
return PI * (self.radio ** 2)
11
12
13
c = Circulo(0, 0, 4.5)
print "Pi:", c.area()
Pi: 63.6172512352
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
56 / 230
class Punto(object):
2
3
4
x = 0
y = 0
5
6
7
8
9 de noviembre de 2014
57 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
58 / 230
class Circulo(object):
2
3
4
5
x = 0
y = 0
radio = 0
6
7
8
9
10
11
12
13
c = Circulo(1, 3, 4)
print "Radio:", c.radio
Radio: 0
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
59 / 230
03. Acceso
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
60 / 230
# encoding: UTF-8
2
3
class T1000(object):
4
5
JEFE = "Skynet"
6
7
8
def saluda_uno(self):
print self.JEFE, "me env
a a eliminarte"
9
10
11
def saluda_dos(self):
print T1000.JEFE, "me env
a a eliminarte"
12
13
14
15
robot = T1000()
robot.saluda_uno()
robot.saluda_dos()
Skynet me env
a a eliminarte
Skynet me env
a a eliminarte
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
61 / 230
Moraleja
Usamos las variables estaticas (o de clase) para los
atributos que son comunes a todos los atributos de la
clase. Los atributos de los objetos se definen en init ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
62 / 230
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
63 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
64 / 230
04. Ejemplo
1
class Persona(object):
2
3
4
5
6
7
8
9
9 de noviembre de 2014
65 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
66 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
67 / 230
class Persona(object):
2
3
4
5
6
7
8
9
10
11
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
68 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
69 / 230
# encoding: UTF-8
2
3
class Persona(object):
4
5
6
# M
axima edad confesada en p
ublico
MAXIMA_EDAD = 35
7
8
9
10
11
12
13
def edad(self):
return min(self._edad, self.MAXIMA_EDAD)
14
15
16
17
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
70 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
71 / 230
class Persona(object):
2
3
4
5
6
7
8
9
9 de noviembre de 2014
72 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
73 / 230
class Persona(object):
2
3
4
5
6
7
8
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
74 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
75 / 230
class Habitacion(object):
_PIN = 9348
3
4
5
6
class CamaraAcorazada(Habitacion):
def __init__(self, PIN):
self._PIN = PIN
7
8
9
p = CamaraAcorazada(2222)
print "PIN:", p._PIN # sobreescribe PIN de Habitacion
PIN: 2222
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
76 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
77 / 230
class Habitacion(object):
__PIN = 9348
3
4
5
6
class CamaraAcorazada(Habitacion):
def __init__(self, PIN):
self.__PIN = PIN
7
8
9
10
p = CamaraAcorazada(2222)
print "PIN1:", p._Habitacion__PIN
print "PIN2:", p._CamaraAcorazada__PIN
PIN1: 9348
PIN2: 2222
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
78 / 230
class Habitacion(object):
__PIN = 9348
3
4
5
6
class CamaraAcorazada(Habitacion):
def __init__(self, PIN):
self.__PIN = PIN
7
8
9
def PIN1(self):
return self._Habitacion__PIN
10
11
12
def PIN2(self):
return self.__PIN
13
14
15
16
p = CamaraAcorazada(2222)
print "PIN1:", p.PIN1()
print "PIN2:"; p.PIN2()
PIN1: 9348
PIN2:
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
79 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
80 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
81 / 230
Moraleja
Usamos foo para variables privadas. En la mayor parte
de las ocasiones, spam no hace falta. Ante la duda,
mejor solo un guion bajo.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
82 / 230
05. M
etodos est
aticos y de clase
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
83 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
84 / 230
05. M
etodos est
aticos y de clase
class Calculadora(object):
2
3
4
5
6
7
def modelo(self):
return self.nombre
8
9
10
11
12
13
14
c = Calculadora("Multivac")
print c.modelo()
print c.suma(4, 8)
Multivac
12
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
85 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
86 / 230
05. M
etodos est
aticos y de clase
class Calculadora(object):
2
3
4
5
6
7
def modelo(self):
return self.nombre
8
9
10
11
@staticmethod
def suma(x, y):
return x + y
12
13
14
15
c = Calculadora("Multivac")
print c.modelo()
print c.suma(4, 8)
Multivac
12
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
87 / 230
05. M
etodos est
aticos y de clase
9 de noviembre de 2014
88 / 230
05. M
etodos est
aticos y de clase
class Calculadora(object):
3
4
5
def modelo(self):
return self.nombre
6
7
8
@staticmethod
def suma(x, y):
return x + y
9
10
11
12
13
print Calculadora.suma(4, 8)
12
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
89 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
90 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
91 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
2
3
class Ameba(object):
4
5
6
7
8
9
10
11
def fision(self):
h1 = Ameba("Primog
enito")
h2 = Ameba("Benjam
n")
return h1, h2
12
13
14
15
16
ameba = Ameba("Foraminifera")
hijo1, hijo2 = ameba.fision()
print "Hijo 1:", hijo1.nombre
print "Hijo 2:", hijo2.nombre
Hijo 1: Primog
enito
Hijo 2: Benjam
n
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
92 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
2
3
class Ameba(object):
4
5
6
7
8
9
10
11
def fision(self):
h1 = Ameba("Primog
enito")
h2 = Ameba("Benjam
n")
return h1, h2
12
13
14
class AmebaCyborg(Ameba):
pass
15
16
17
18
19
9 de noviembre de 2014
93 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
class Ameba(object):
3
4
5
6
7
8
9
10
11
12
13
def fision(self):
cls1 = self.__class__
h1 = cls1("Primog
enito")
# O tambi
en...
cls2 = type(self)
h2 = cls2("Benjam
n")
return h1, h2
14
15
16
17
18
ameba = Ameba("Foraminifera")
hijo1, hijo2 = ameba.fision()
print "Hijo 1:", hijo1.nombre
print "Hijo 2:", hijo2.nombre
Hijo 1: Primog
enito
Hijo 2: Benjam
n
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
94 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
95 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
class Ameba:
3
4
5
6
7
8
9
10
11
12
def fision(self):
clase = type(self)
print "Mi tipo es:", clase
h1 = clase("Primog
enito")
h2 = clase("Benjam
n")
return h1, h2
13
14
15
ameba = Ameba("Foraminifera")
ameba.fision()
Mi tipo es: <type instance>
Traceback (most recent call last):
File "./code/05/56-new-object-problem-3.py", line 15, in <module>
ameba.fision()
File "./code/05/56-new-object-problem-3.py", line 10, in fision
h1 = clase("Primog
enito")
TypeError: must be classobj, not str
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
96 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
97 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
2
3
class Ameba(object):
4
5
6
7
8
9
10
11
12
@classmethod
def fision(cls):
h1 = cls("Primog
enito")
h2 = cls("Benjam
n")
return h1, h2
13
14
15
16
17
ameba = Ameba("Foraminifera")
hijo1, hijo2 = ameba.fision()
print "Hijo 1:", hijo1.nombre
print "Hijo 2:", hijo2.nombre
Hijo 1: Primog
enito
Hijo 2: Benjam
n
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
98 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
99 / 230
05. M
etodos est
aticos y de clase
# encoding: UTF-8
2
3
class Ameba(object):
4
5
6
7
8
9
10
11
12
13
def fision(self):
cls = type(self)
ascendencia = ", hijo de " + self.nombre
h1 = cls("Primog
enito" + ascendencia)
h2 = cls("Benjam
n" + ascendencia)
return h1, h2
14
15
16
17
18
ameba = Ameba("Foraminifera")
hijo1, hijo2 = ameba.fision()
print "Hijo 1:", hijo1.nombre
print "Hijo 2:", hijo2.nombre
Hijo 1: Primog
enito, hijo de Foraminifera
Hijo 2: Benjam
n, hijo de Foraminifera
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
100 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
101 / 230
05. M
etodos est
aticos y de clase
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
102 / 230
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
105 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
106 / 230
# encoding: UTF-8
2
3
import math
4
5
class Circulo(object):
6
7
8
9
10
11
12
13
14
c = Circulo(1)
print "Radio:", c.radio
print "
Area:", c.area
print
15
16
17
18
c.radio = 2
print "Radio:", c.radio
print "
Area:", c.area
Radio: 1
Area: 3.14159265359
Radio: 2
Area: 3.14159265359
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
107 / 230
06. getters
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
108 / 230
# encoding: UTF-8
import math
3
4
class Circulo(object):
5
6
7
8
9
10
def area(self):
return math.pi * self.radio ** 2
11
12
13
14
15
16
17
c = Circulo(1)
print "Radio:", c.radio
print "
Area:", c.area()
c.radio = 2
print "Radio:", c.radio
print "
Area:", c.area()
Radio: 1
Area: 3.14159265359
Radio: 2
Area: 12.5663706144
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
109 / 230
06. getters
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
110 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
111 / 230
class Circulo(object):
2
3
4
5
6
7
8
9
c = Circulo(13)
print "Radio:", c.radio
c.radio = -2
print "Radio:", c.radio
Radio: 13
Radio: -2
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
112 / 230
06. setters
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
113 / 230
# encoding: UTF-8
class Circulo(object):
3
4
5
6
7
8
9
10
11
12
13
14
15
c = Circulo(3.5)
print "Radio:", c._radio
c.set_radio(-2)
print "Radio:", c._radio
Radio: 3.5
Traceback (most recent call last):
File "./code/06/603-setter-example-1.py", line 14, in <module>
c.set_radio(-2)
File "./code/06/603-setter-example-1.py", line 9, in set_radio
raise ValueError("radio debe ser un n
umero no negativo")
ValueError: radio debe ser un n
umero no negativo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
114 / 230
06. Mutadores
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
115 / 230
# encoding: UTF-8
2
3
class CajaFuerte(object):
4
5
6
7
8
9
10
def get_PIN(self):
print "Enviando copia a la NSA..."
return self._PIN
11
12
13
hucha = CajaFuerte(7821)
print "PIN:", hucha.get_PIN()
PIN: Enviando copia a la NSA...
7821
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
116 / 230
06. Propiedades
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
117 / 230
# encoding: UTF-8
2
3
class CajaFuerte(object):
4
5
6
7
8
9
10
11
@property
def PIN(self):
print "Enviando copia a la NSA..."
return self._PIN
12
13
14
15
16
17
@PIN.setter
def PIN(self, PIN):
if len(str(PIN)) != 4:
raise ValueError("PIN ha de tener cuatro d
gitos")
self._PIN = PIN
18
19
20
21
hucha = CajaFuerte(7814)
print "PIN:", hucha.PIN
hucha.PIN = 880
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
118 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
119 / 230
06. Propiedades
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
120 / 230
# encoding: UTF-8
2
3
import math
4
5
class Circulo(object):
6
7
8
9
10
11
12
@property
def area(self):
return math.pi * self.radio ** 2
13
14
15
16
17
c = Circulo(1)
print "Radio:", c.radio
print "
Area:", c.area
print
18
19
20
21
c.radio = 2
print "Radio:", c.radio
print "
Area:", c.area
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
121 / 230
Radio: 1
Area: 3.14159265359
Radio: 2
Area: 12.5663706144
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
122 / 230
# encoding: UTF-8
2
3
class Circulo(object):
4
5
6
7
8
9
10
@property
def radio(self):
return self._radio
11
12
13
14
15
16
@radio.setter
def radio(self, radio):
if radio < 0:
raise ValueError("radio debe ser un n
umero no negativo")
self._radio = radio
17
18
19
20
21
c = Circulo(13)
print "Radio:", c.radio
c.radio = -2
print "Radio:", c.radio
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
123 / 230
Radio: 13
Traceback (most recent call last):
File "./code/06/607-property-fset.py", line 20, in <module>
c.radio = -2
File "./code/06/607-property-fset.py", line 15, in radio
raise ValueError("radio debe ser un n
umero no negativo")
ValueError: radio debe ser un n
umero no negativo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
124 / 230
06. deleter
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
125 / 230
# encoding: UTF-8
class CajaFuerte(object):
def __init__(self, PIN):
self._PINs = []
self.PIN = PIN
6
7
8
9
10
11
12
@property
def PIN(self):
try:
return self._PINs[-1]
except IndexError:
return None
13
14
15
16
17
18
@PIN.setter
def PIN(self, PIN):
if len(str(PIN)) != 4:
raise ValueError("PIN ha de tener cuatro d
gitos")
self._PINs.append(PIN)
19
20
21
22
@PIN.deleter
def PIN(self):
del self._PINs[:]
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
126 / 230
3
4
5
6
7
8
9
10
hucha = modulo.CajaFuerte(7814)
print "PIN:", hucha.PIN
hucha.PIN = 8808
print "PIN:", hucha.PIN
print "Historial:", hucha._PINs
del hucha.PIN
print "PIN:", hucha.PIN
PIN: 7814
PIN: 8808
Historial: [7814, 8808]
PIN: None
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
127 / 230
06. @property
Poniendonos un poco tecnicos, lo que esta ocurriendo
con el decorador @property es que la funcion se esta
convirtiendo en en un getter para un atributo de solo
lectura de ese mismo nombre.
Este objeto property nos ofrece a su vez los metodos getter, setter y
deleter, que podemos usar como decoradores para copiar la
propiedad y ajustar su correspondiente funcion de acceso.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
128 / 230
06. docstring
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
129 / 230
# encoding: UTF-8
2
3
import math
4
5
class Circulo(object):
6
7
8
9
10
11
12
13
@property
def area(self):
"""Devuelve al a
rea del c
rculo. """
return math.pi * self.radio ** 2
14
15
16
17
18
c = Circulo(3.4)
print "Radio:", c.radio
print "
Area:", c.area
print "Docstring:", Circulo.area.__doc__
Radio: 3.4
Area: 36.3168110755
Docstring: Devuelve al
area del c
rculo.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
130 / 230
06. @property
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
131 / 230
# encoding: UTF-8
class Circulo(object):
3
4
5
6
7
8
9
@property
def radio(self):
return self._radio
10
11
12
13
14
15
@radio.setter
def set_radio(self, radio):
if radio < 0:
raise ValueError("radio debe ser un n
umero no negativo")
self._radio = radio
16
17
18
c = Circulo(13)
print "Radio:", c.radio
Traceback (most recent call last):
File "./code/06/610-name-unmatch.py", line 17, in <module>
c = Circulo(13)
File "./code/06/610-name-unmatch.py", line 5, in __init__
self.radio
= radio
Vctor
Terr
on (IAA-CSIC)
Clases en Python: lo est
as haciendo mal
9 de noviembre de 2014
132 / 230
06. property()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
133 / 230
class CajaFuerte(object):
def __init__(self, PIN):
self.PIN = PIN
4
5
6
def get_PIN(self):
return self._PIN
7
8
9
10
11
12
13
def delete_PIN(self):
self.PIN = None
14
15
16
17
18
19
hucha = CajaFuerte(7814)
print "PIN:", hucha.PIN
print "Docstring:", CajaFuerte.PIN.__doc__
Enviando copia a la NSA...
PIN: 7814
Docstring: La clave de acceso
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
134 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
135 / 230
class CajaFuerte(object):
2
3
4
5
6
7
8
9
10
11
def delete_PIN(self):
self.PIN = None
12
13
14
15
16
17
hucha = CajaFuerte(7814)
del hucha.PIN
print "PIN:", hucha.PIN
Enviando copia a la NSA...
Enviando copia a la NSA...
PIN:
Traceback (most recent call last):
File "./code/06/612-setter-and-deleter.py", line 17, in <module>
print
Vctor
Terr
on"PIN:",
(IAA-CSIC)hucha.PIN
Clases en Python: lo est
as haciendo mal
9 de noviembre de 2014
136 / 230
06. property()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
137 / 230
# encoding: UTF-8
2
3
import math
4
5
class Circulo(object):
6
7
8
9
10
11
12
@property
def area(self):
return math.pi * self.radio ** 2
13
14
15
16
c = Circulo(1.5)
print "
Area:", c.area
del c.area
Area: 7.06858347058
Traceback (most recent call last):
File "./code/06/613-deleter-error.py", line 16, in <module>
del c.area
AttributeError: cant delete attribute
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
138 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
139 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
140 / 230
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
141 / 230
Moraleja
No usamos setters ni getters, sino simple acceso a
atributos. Si y cuando necesitemos alguna logica de
acceso, podemos reemplazar estos atributos por
funciones y usar @properties.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
142 / 230
07.
str () y
repr ()
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
143 / 230
07.
07.
str () y
repr ()
str () y repr ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
144 / 230
07.
str () y
repr ()
# encoding: UTF-8
2
3
class Triangulo(object):
4
5
6
7
8
9
10
11
@property
def area(self):
return (self.base * self.altura) / 2.0
12
13
14
15
t = Triangulo(2, 3)
print "Tri
angulo:", t
print "
Area:", t.area
Tri
angulo: <__main__.Triangulo object at 0x402b966c>
Area: 3.0
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
145 / 230
07.
07.
str () y
repr ()
str ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
146 / 230
07.
07.
1
str () y
repr ()
str () Ejemplo
# encoding: UTF-8
2
3
class Triangulo(object):
4
5
6
7
8
9
10
11
@property
def area(self):
return (self.base * self.altura) / 2.0
12
13
14
15
def __str__(self):
msg = "Tri
angulo de base {0} y altura {1}"
return msg.format(self.base, self.altura)
16
17
18
19
t = Triangulo(2, 3)
print str(t)
print "
Area:", t.area
Tri
angulo de base 2 y altura 3
Area: 3.0
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
147 / 230
07.
07.
str () y
repr ()
str ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
148 / 230
07.
07.
1
str () y
repr ()
str () Mejor as
# encoding: UTF-8
2
3
4
5
6
class Triangulo(object):
def __init__(self, base, altura):
self.base = base
self.altura = altura
7
8
9
10
@property
def area(self):
return (self.base * self.altura) / 2.0
11
12
13
14
15
def __str__(self):
clase = type(self).__name__
msg = "{0} de base {1} y altura {2}"
return msg.format(clase, self.base, self.altura)
16
17
18
19
t = Triangulo(2, 3)
print t
print "
Area:", t.area
Triangulo de base 2 y altura 3
Area: 3.0
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
149 / 230
07.
07.
str () y
repr ()
str ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
150 / 230
07.
07.
str () y
repr ()
repr ()
El objetivo de repr () es ser inequvoco.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
151 / 230
07.
07.
str () y
repr ()
repr ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
152 / 230
07.
07.
1
str () y
repr ()
repr () No definido
class Triangulo(object):
2
3
4
5
6
7
8
9
10
def __str__(self):
clase = type(self).__name__
msg = "{0} de base {1} y altura {2}"
return msg.format(clase, self.base, self.altura)
11
12
13
t = Triangulo(2, 3)
print repr(t)
<__main__.Triangulo object at 0x402b962c>
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
153 / 230
07.
07.
str () y
repr ()
repr ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
154 / 230
07.
07.
1
str () y
repr ()
repr () y eval()
class Triangulo(object):
2
3
4
5
6
7
8
9
10
def __str__(self):
clase = type(self).__name__
msg = "{0} de base {1} y altura {2}"
return msg.format(clase, self.base, self.altura)
11
12
13
14
15
def __repr__(self):
clase = type(self).__name__
msg = "{0}({1}, {2})"
return msg.format(clase, self.base, self.altura)
16
17
18
19
t = Triangulo(2, 3)
print repr(t)
print eval(repr(t))
Triangulo(2, 3)
Triangulo de base 2 y altura 3
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
155 / 230
07.
07.
str () y
repr ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
156 / 230
07.
07.
1
str () y
repr ()
class Triangulo(object):
2
3
4
5
6
7
8
9
10
def __repr__(self):
clase = type(self).__name__
msg = "{0}({1}, {2})"
return msg.format(clase, self.base, self.altura)
11
12
13
14
t = Triangulo(2, 3)
print str(t)
print repr(t)
Triangulo(2, 3)
Triangulo(2, 3)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
157 / 230
07.
07.
str () y
repr ()
Vctor Terr
on (IAA-CSIC)
repr ().
9 de noviembre de 2014
158 / 230
07.
07.
str () y
repr ()
import datetime
2
3
4
5
ahora = datetime.datetime.now()
print "str() :", str(ahora)
print "repr():", repr(ahora)
str() : 2014-11-09 05:12:13.425097
repr(): datetime.datetime(2014, 11, 9, 5, 12, 13, 425097)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
159 / 230
07.
07.
str () y
repr ()
str () y repr ()
Moraleja
repr () es para desarrolladores,
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
160 / 230
08. collections.namedtuple()
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
163 / 230
08. collections.namedtuple()
08. collections.namedtuple()
El modulo collections es genial, y una de
sus joyas es namedtuple()
Hay ocasiones en las que tenemos necesitamos clases que no son
mas que contenedores de atributos. Por ejemplo, podramos definir
la clase Punto para almacenar las coordenadas (x, y, z) de un punto
en el espacio tridimensional.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
164 / 230
08. collections.namedtuple()
class Punto(object):
""" Punto (x, y, z) en un espacio tridimensional. """
4
5
6
7
8
9
10
11
12
p = Punto(3, 1, 5)
print "x:", p.x
print "y:", p.y
print "z:", p.z
x: 3
y: 1
z: 5
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
165 / 230
08. collections.namedtuple()
08. collections.namedtuple()
Aunque no necesitemos hacer nada mas con estos
atributos, hemos tenido que definir un init () lleno de
aburridas asignaciones.
Y, al no haber definido str () ni repr (), ni siquiera
podemos imprimir por pantalla nuestro objeto de la
forma que esperaramos.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
166 / 230
08. collections.namedtuple()
class Punto(object):
""" Punto (x, y, z) en un espacio tridimensional. """
3
4
5
6
7
8
9
10
p = Punto(3, 1, 5)
print p
<__main__.Punto object at 0x402b958c>
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
167 / 230
08. collections.namedtuple()
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
168 / 230
08. collections.namedtuple()
class Punto(object):
""" Punto (x, y, z) en un espacio tridimensional. """
3
4
5
6
7
8
9
10
11
def __repr__(self):
args = (type(self).__name__, self.x, self.y, self.z)
return "{0}({1}, {2}, {3})".format(*args)
12
13
14
p1 = Punto(3, 1, 5)
p2 = Punto(3, 1, 5)
15
16
17
9 de noviembre de 2014
169 / 230
08. collections.namedtuple()
class Punto(object):
""" Punto (x, y, z) en un espacio tridimensional. """
3
4
5
6
7
8
9
10
11
def __repr__(self):
args = (type(self).__name__, self.x, self.y, self.z)
return "{0}({1}, {2}, {3})".format(*args)
12
13
14
15
16
9 de noviembre de 2014
170 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
171 / 230
08. collections.namedtuple()
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
172 / 230
08. collections.namedtuple()
import collections
Punto = collections.namedtuple("Punto", "x y z")
3
4
5
6
7
p = Punto(3, 1, 5)
print "x:", p.x
print "y:", p.y
print "z:", p.z
8
9
10
11
p2 = Punto(3, 1, 5)
print p2
print p == p2
x: 3
y: 1
z: 5
Punto(x=3, y=1, z=5)
True
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
173 / 230
08. collections.namedtuple()
08. collections.namedtuple()
Lo que namedtuple(), una factory function, nos devuelve,
es una nueva clase que hereda de tuple pero que tambien
permite acceso a los atributos por nombre.
Nada mas y nada menos pero al ser una subclase significa que
todos los metodos magicos que necesitabamos ya estan
implementados.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
174 / 230
08. collections.namedtuple()
# encoding: UTF-8
2
3
import collections
4
5
6
7
8
9
10
11
p = Punto(4, 3, 7)
print "x:", p.x
print "y:", p[1]
print "z:", p[-1]
print "Tama~
no:", len(p)
x: 4
y: 3
z: 7
Tama~
no: 3
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
175 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
176 / 230
08. collections.namedtuple()
# encoding: UTF-8
2
3
import collections
4
5
6
7
8
9
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
177 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
178 / 230
08. collections.namedtuple()
# encoding: UTF-8
2
3
4
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
179 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
180 / 230
08. collections.namedtuple()
# encoding: UTF-8
2
3
4
5
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
181 / 230
08. collections.namedtuple()
08. typename
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
182 / 230
08. collections.namedtuple()
import collections
2
3
4
5
6
7
8
p = cls(4, 3, 8)
print p
<class __main__.Punto>
Nombre: Punto
Punto(x=4, y=3, z=8)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
183 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
184 / 230
08. collections.namedtuple()
import collections
2
3
import math
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
p1 = Punto(3, 1, 5)
p2 = Punto(5, 2, 7)
print "Distancia:", p1.distancia(p2)
print
print "MRO:", Punto.__mro__
Distancia: 3.0
MRO: (<class __main__.Punto>, <class __main__.Punto>, <type
tuple>, <type object>)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
185 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
186 / 230
08. collections.namedtuple()
import collections
import math
3
4
5
6
7
8
9
10
11
12
13
14
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
187 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
188 / 230
08. collections.namedtuple()
import collections
import math
3
4
5
6
7
8
9
10
11
12
13
9 de noviembre de 2014
189 / 230
08. collections.namedtuple()
import collections
import math
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def to_zero(self):
""" Distancia al origen de coordenadas. """
cls = type(self)
origen = cls(0, 0, 0)
return self.distancia(origen)
18
19
20
p = Punto(3, 4, 2)
print "Distancia:", p.to_zero()
Distancia: 5.38516480713
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
190 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
191 / 230
08. collections.namedtuple()
import collections
Punto = collections.namedtuple("Punto", "x y z", verbose=True)
class Punto(tuple):
Punto(x, y, z)
__slots__ = ()
_fields = (x, y, z)
def __new__(_cls, x, y, z):
Create new instance of Punto(x, y, z)
return _tuple.__new__(_cls, (x, y, z))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
Make a new Punto object from a sequence or iterable
result = new(cls, iterable)
if len(result) != 3:
raise TypeError(Expected 3 arguments, got %d %
len(result))
return result
def __repr__(self):
Return a nicely formatted representation string
return Punto(x=%r, y=%r, z=%r) % self
def _asdict(self):
Return a new OrderedDict which maps field names to their
values
Vctor Terr
on (IAA-CSIC)
Clases en Python: lo est
as haciendo mal
9 de noviembre de 2014
192 / 230
08. collections.namedtuple()
08. asdict()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
193 / 230
08. collections.namedtuple()
import collections
2
3
4
5
6
7
8
9 de noviembre de 2014
194 / 230
08. collections.namedtuple()
08. replace()
Y por ultimo al heredar de tuple, las namedtuples son,
por definicion, inmutables. Pero no tenemos por que
abandonar toda esperanza.
Usando el metodo replace() podemos cambiar el valor
de uno o mas atributos, aunque lo que obtenemos es un
nuevo objeto (ya que el original no puede ser
modificado!)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
195 / 230
08. collections.namedtuple()
import collections
2
3
4
5
6
7
8
p2 = p1._replace(x = 7)
print "Punto 2:", p2
9
10
11
12
13
14
print
p3.x = 3 # AttributeError
Punto 1: Punto(x=8, y=1, z=3)
Punto 2: Punto(x=7, y=1, z=3)
Punto 3: Punto(x=8, y=3, z=-1)
Traceback (most recent call last):
File "./code/08/816-namedtuple-replace.py", line 14, in <module>
p3.x = 3 # AttributeError
AttributeError: cant set attribute
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
196 / 230
08. collections.namedtuple()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
197 / 230
08. collections.namedtuple()
08. collections.namedtuple()
What are named tuples in Python?
http://stackoverflow.com/q/2970608/184363
namedtuple - Python Module of the Week
http://pymotw.com/2/collections/namedtuple.html
Moraleja
Usa namedtuple() siempre que puedas.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
198 / 230
09.
init () y
new ()
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
199 / 230
09.
09.
init () y
new ()
init () y new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
200 / 230
09.
init () y
new ()
1
2
class Pesos(tuple):
pass
3
4
5
p = Pesos([0.75, 0.25])
print "Pesos:", p
Pesos: (0.75, 0.25)
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
201 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
202 / 230
09.
init () y
new ()
class Pesos(tuple):
pass
3
4
5
6
9 de noviembre de 2014
203 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
204 / 230
09.
init () y
new ()
class Pesos(tuple):
2
3
4
5
@property
def total(self):
return sum(self)
6
7
8
9
10
11
12
13
p1 = Pesos([0.25, 0.75])
print "Pesos 1:", p1
14
15
16
print
p2 = Pesos([0.50, 0.75, 0.25]) # ValueError
Pesos 1: (0.25, 0.75)
Traceback (most recent call last):
File "./code/09/902-why-we-need-new-2.py", line 16, in <module>
p2 = Pesos([0.50, 0.75, 0.25]) # ValueError
File "./code/09/902-why-we-need-new-2.py", line 10, in __init__
raise ValueError(msg)
ValueError:
la suma de los Clases
pesos
ha deloser
Vctor Terr
on (IAA-CSIC)
en Python:
est
as uno
haciendo mal
9 de noviembre de 2014
205 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
206 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
207 / 230
09.
init () y
new ()
# encoding: UTF-8
2
3
class Pesos(tuple):
4
5
6
7
@property
def total(self):
return sum(self)
8
9
10
11
12
13
14
9 de noviembre de 2014
208 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
209 / 230
09.
09.
init () y
new ()
init () es el inicializador
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
210 / 230
09.
init () y
new ()
class Pesos(tuple):
2
3
4
5
@property
def total(self):
return sum(self)
6
7
8
9
10
11
12
13
9 de noviembre de 2014
211 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
212 / 230
09.
init () y
new ()
# encoding: UTF-8
2
3
class Pesos(tuple):
4
5
6
7
@property
def total(self):
return sum(self)
8
9
10
11
12
13
14
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
213 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
214 / 230
09.
09.
init () y
new ()
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
215 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
216 / 230
09.
init () y
new ()
# encoding: UTF-8
2
3
4
5
6
variable = "Python"
print "Antes :", variable
variable.__init__("Java") # nooo!
print "Despu
es:", variable
Antes : Python
Despu
es: Python
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
217 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
218 / 230
09.
init () y
new ()
2
3
class Pesos(tuple):
4
5
6
7
8
9
10
11
12
13
9 de noviembre de 2014
219 / 230
09.
init () y
new ()
2
3
class Pesos(tuple):
4
5
6
7
8
9
10
11
12
13
9 de noviembre de 2014
220 / 230
09.
init () y
new ()
2
3
class Pesos(tuple):
4
5
6
7
8
9
10
11
12
@property
def total(self):
return sum(self)
13
14
15
16
p = Pesos([2, 1, 3])
print "Pesos:", p
print "Total:", p.total
Pesos: (0.3333333333333333, 0.16666666666666666, 0.5)
Total: 1.0
Y ya no necesitamos
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
221 / 230
09.
init () y
new ()
09. AnswerToEverything
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
222 / 230
09.
init () y
new ()
# encoding: UTF-8
2
3
class AnswerToEverything(object):
4
5
6
7
8
9
10
11
12
13
14
15
def __str__(self):
return str(self.valor)
16
17
18
respuesta = AnswerToEverything(23)
print "Respuesta:", respuesta
En __new__()!
En __init__()!
Respuesta: 42
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
223 / 230
09.
init () y
new ()
# encoding: UTF-8
2
3
class AnswerToEverything(object):
4
5
6
7
8
9
10
11
12
13
14
respuesta = AnswerToEverything(23)
print "Respuesta:", respuesta
En __new__()!
Respuesta: 42
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
224 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
225 / 230
09.
init () y
new ()
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
226 / 230
09.
09.
init () y
new ()
init () y new ()
Pythons use of new and init ?
https://stackoverflow.com/q/674304/184363
Overriding the new method (GvR)
https://www.python.org/download/releases/2.2/
descrintro/#__new__
Moraleja
Es new () quien crea el nuevo objeto. La mayor parte
del tiempo solo necesitamos tenerlo en cuenta cuando
heredamos de clases inmutables.
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
227 / 230
Eplogo
Indice
1
2
3
4
5
6
7
8
9
10
11
12
Introduccion
00. Heredando de object (new-style)
01. super()
02. El primer parametro: self
03. Variables de clase (estaticas)
04. Atributos privados y ocultos
05. Metodos estaticos y de clase
06. Propiedades (@property)
07. str () y repr ()
08. collections.namedtuple()
09. init () y new ()
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
228 / 230
Eplogo
Vctor Terr
on (IAA-CSIC)
9 de noviembre de 2014
229 / 230
Eplogo
9 de noviembre de 2014
230 / 230