Inmersión en Python II
Contenido
Ordenación
# Ordena diccionarios por valor >>> d = {'a':3, 'b':7, 'c':5} >>> l.sort(key=lambda x: x[1]) >>> l [('a', 3), ('c', 5), ('b', 7)]
Excepciones
try: f = open("file.txt") except IOError, e: # tratar excepción
Más complejo:
try: # código con riesgo except Exception, e: # captura excepción else: # si no ha saltado ninguna excepción finally: # ejecuta al final
Importar módulos
import math from math import sin import longname as ln math.sqrt(9) sin(30) ln(2)
Clases y objetos
¿Qué son?
- Un objeto es una entidad que agrupa un estado y una funcionalidad relacionadas.
- En Python un objeto es un conjunto de atributos
- Una clase permite crear nuevos objetos que comparten los mismos atributos
- Muy importantes para optimizar/reutilizar mejor el código
En Python todo son objetos
print (123).__class__ print zip.__class__ print list.__class__ import os ; print os.__class__
Y todo objeto tiene una clase.
Clase = Arquetipo del objeto.
class Estudiante(object): def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad maria = Estudiante('María', 19) print maria.nombre
self
Explícitamente hay que usar el self al definir las clases en Python. Se refiere a la instancia concreta del objeto. Aparecerá como primer parámetro en la definición de los métodos. Pero no se usa al llamar a las clases o a los métodos. De forma automática, Python pasa la instancia del objeto.
Clase = función
- Al ejecutar clase se produce un nuevo valor.
- El objeto tiene los mismos atributos que la clase salvo el operador ()
- Inicializa el objeto con el método __init__
- Le pasa objeto + parámetros a la clase.
Método __init__
Es un método opcional. Se usará cuando hay que inicializar datos.
Un método es una función asociada a un objeto
class Estudiante(object): def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def saluda(self): return 'Hola, me llamo %s' % self.nombre maria = Estudiante('María', 19) print maria.saluda()
- Primer parametro es la instancia.
- self por convención
- Todas las clases heredan de object
- Los atributos pueden añadirse, borrarse, modificarse, en cualquier momento
- En Python todo es público
- Por convención, lo privado empieza por _
Ejemplo: self._atributo
- ¡Python no es Java!: No "setters" y "getters"
maria.edad += 1
Herencia
class Base (object): def method(self): print "base.method()" class Deriv (Base): def method ( self ): print "deriv.method()" def other (self): print "deriv.other()" # método añadido
- Si el padre necesitaba parámetros, hay que llamar a su método __init__
class Persona(object): def __init__(self, nombre): self.nombre = nombre class Estudiante(Persona): def __init__(self, nombre, curso): super(Estudiante, self).__init__(nombre) self.curso = curso
Métodos especiales
__init__(self, ...) __new__(cls, args) __del__(self) __str__(self) __cmp__(self, otro) __len__(self) __getitem__(self, key) __setitem__(self, key, valor) ...
class Estudiante(object): def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def saluda(self): return 'Hola, me llamo %s' % self.nombre def __str__(self): return self.nombre def __repr__(self): return self.nombre def __cmp__(self, per): '''p es otro objeto de tipo persona''' return cmp(self.nombre, per.nombre) if __name__ == '__main__': maria = Estudiante('María', 19) luis = Estudiante('Luis', 21) ana = Estudiante('Ana', 23) estudiantes = [maria, luis, ana] print sorted(estudiantes)
Métodos estáticos
En Python los métodos estáticos se usan mucho menos que en Java porque se pueden crear funciones estándar en los módulos. En java un método estático y un método de clase son lo mismo. En Python no. Supón que a() es una función definida en la clase Madre. Cuando una clase hija hereda:
- Si a() es un @staticmethod, Hija.a() se refiere a la definición de la clase Madre.
- Si a() es un @classmethod, Hija.a() apunta a la definición de la subclase.
Es decir:
- @staticmethod es una función definida dentro de una clase. Se puede llamar sin haber instanciado la clase antes. Su definición es inmutable por herencia.
- @classmethod es una función que a la que se puede llamar sin instanciar la clase, pero su definición sigue la subclase, no a la clase madre via herencia. Por eso su primer argumento es cls (class).
class Objeto(object): contador = 0 # contador es un atributo estático def __init__(self, valor): self.valor = valor Objeto.contador += 1 @staticmethod def total(): return Objeto.contador uno = Objeto('Primero') dos = Objeto('Segundo') tres = Objeto('Tercero') print 'Hemos creado', Objeto.total(), 'objetos.' print 'Soy el objeto', dos.valor, 'de', dos.total(), 'objetos.'
Salida:
Hemos creado 3 objetos. Soy el objeto Segundo de 3 objetos.
class Objeto(object): @classmethod def metodo_de_clase(cls): print "Invocado desde la clase %s " % cls class ObjetoHijo(Objeto): pass
Ejemplo de uso:
>>> Objeto.metodo_de_clase() Invocado desde la clase <class '__main__.Objeto'> >>> ObjetoHijo.metodo_de_clase() Invocado desde la clase <class '__main__.ObjetoHijo'> >>> o = Objeto() >>> o.metodo_de_clase() Invocado desde la clase <class '__main__.Objeto'> >>> h = ObjetoHijo() >>> h.metodo_de_clase() Invocado desde la clase <class '__main__.ObjetoHijo'>
Instalar módulos de terceros
http://docs.python.org/install/index.html
Método habitual
En linux puedes usar el sistema de paquetes de la distribución o instalar de la fuente del programa. Para instalar de la fuente:
- Descarga la fuente (archivo comprimido o desde un sistema de gestión de código: mercurial, git, subversion ...)
- Colócate dentro del directorio del paquete. Comprueba las dependencias (fichero README)
- Ejecuta dentro:
$ python setup.py install
Esto instala el paquete para todo el python general que estamos usando. Necesitas permisos de administrador. Si el paquete tiene extensiones en C necesitas un compilador de C y las librerías de desarrollo de Python (algunas distros de linux instalan aparte python-dev) Algunos paquetes necesitan setuptools: descarga http://peak.telecommunity.com/dist/ez_setup.py y ejecuta el archivo.
Instalar con easy_install o pip
$ easy_install <nombre de paquete> $ pip install <nombre de paquete>
Si pip no está instalado:
$ easy_install pip
Uso de Virtualenv
Si no interesa instalar el módulo para todo el python (un servidor, probar varias versiones de un producto, permisos locales, etc) usamos virtualenv:
Instalar virtualenv
- Descargar e instalar de http://pypi.python.org/pypi/virtualenv
- o usar el sistema de paquetes de la distro.
Crear entorno
Se puede crear entorno limpio:
$ virtualenv --no-site-packages proyectocool
o usando los paquetes ya instalados en el sistema:
$ virtualenv proyectocool
Para activar el entorno
$ source proyectocool/bin/activate (proyectocool) $
Para desactivar el entorno
$ deactivate
Ahora cuando está activado el entorno todo lo que instalamos con easy_install, pip o python setup.py se instala en el entorno virtual.