Diferencia entre revisiones de «Curso Python DGA 2011/inmersion python/contenidos»
(→=Instalar virtualenv) |
|||
(46 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 1: | Línea 1: | ||
{{:Curso Python DGA 2011/inmersion python/nav}} | {{:Curso Python DGA 2011/inmersion python/nav}} | ||
− | {{MiTitulo| | + | {{MiTitulo| Contenidos}} |
+ | {{TOC | right}} | ||
+ | {{Tip | | ||
+ | Puedes ver los contenidos en formato presentación: [[Curso_Python_DGA_2011/inmersion_python/contenidos/slides1 | Inmersión I]] :: [[Curso_Python_DGA_2011/inmersion_python/contenidos/slides2 | Inmersión II]] | ||
+ | }} | ||
==¿Python?== | ==¿Python?== | ||
<br /> | <br /> | ||
− | {{Puntos clave|Title= | + | {{Puntos clave|Title=Peculiaridades| |
* Interpretado, pero compilado a bytecode. | * Interpretado, pero compilado a bytecode. | ||
* Tipado dinámico, pero fuertemente tipado | * Tipado dinámico, pero fuertemente tipado | ||
Línea 20: | Línea 24: | ||
}} | }} | ||
+ | == Instalación == | ||
+ | Sitio de referencia: http://python.org/download/ | ||
+ | En linux normalmente suele estar instalado el intérprete. Puedes usar el sistema de paquetes de tu distribución o instalar desde la fuente del programa (necesitas compilador). | ||
+ | En Windows usa el instalador apropiado. | ||
− | |||
− | |||
{{Recursos de la Web|Title=Echa un vistazo| | {{Recursos de la Web|Title=Echa un vistazo| | ||
Guía de instalación y uso: http://docs.python.org/using/index.html (en inglés) | Guía de instalación y uso: http://docs.python.org/using/index.html (en inglés) | ||
Línea 33: | Línea 39: | ||
== Mi primer programa == | == Mi primer programa == | ||
+ | === Ejecutables linux === | ||
+ | <source lang="python"> | ||
+ | #!/usr/bin/env python | ||
+ | </source> | ||
+ | |||
+ | <source lang="bash"> | ||
+ | $ chmod +x hello.py | ||
+ | $ ./hello.py | ||
+ | </source> | ||
=== Herramientas para programar === | === Herramientas para programar === | ||
Línea 45: | Línea 60: | ||
>>> print "Hola, mundo" | >>> print "Hola, mundo" | ||
Hola, mundo | Hola, mundo | ||
− | >>> | + | >>> impuesto = 12.5 / 100 |
− | + | >>> precio = 100.50 | |
− | >>> | + | >>> precio * impuesto |
− | + | 12.5625 | |
− | + | >>> precio + _ | |
− | + | 113.0625 | |
− | + | >>> round(_, 2) | |
− | + | 113.06 | |
− | > | + | |
− | + | ||
− | >>> | + | |
− | + | ||
− | >>> | + | |
− | + | ||
</source> | </source> | ||
=== Un programa que hace algo === | === Un programa que hace algo === | ||
− | + | ||
<source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | # No declaramos variables, ponemos nombres a objetos | ||
coches = 100 | coches = 100 | ||
capacidad_coche = 4.0 | capacidad_coche = 4.0 | ||
Línea 80: | Línea 90: | ||
print "Tenemos que poner una media de", media_pasajeros_coche, "por coche hoy." | print "Tenemos que poner una media de", media_pasajeros_coche, "por coche hoy." | ||
</source> | </source> | ||
+ | |||
+ | === Sobre el estilo === | ||
+ | http://docs.python.org.ar/tutorial/controlflow.html#intermezzo-estilo-de-codificacion | ||
+ | * minúsculas | ||
+ | * guiones bajo_entre_palabras | ||
+ | * no pueden comenzar con números | ||
+ | * ni se pueden usar palabras reservadas (file, assert, class, def | ||
+ | |||
+ | {{Tip| Mirad PEP8}} | ||
+ | |||
+ | == Introspección == | ||
+ | * dir(<objeto>) | ||
+ | * help(<objeto>.<metodo>) | ||
+ | |||
+ | |||
+ | == Operaciones con números == | ||
+ | Las básicas como en otros lenguajes. Operaciones matemáticas '''import math'''. | ||
+ | Observa: | ||
+ | <source lang="python" enclose="div"> | ||
+ | # Cuidado! | ||
+ | >>> 5/2 | ||
+ | 2 | ||
+ | >>> 5/2. | ||
+ | 2.5 | ||
+ | # Conversión automática | ||
+ | >>> 10 ** 10 | ||
+ | 10000000000L | ||
+ | </source> | ||
+ | |||
+ | === Casting === | ||
+ | <source lang="python"> | ||
+ | >>> num = '2.3' | ||
+ | >>> float(num) | ||
+ | 2.3 | ||
+ | >>> int('2') | ||
+ | 2 | ||
+ | >>> long('2') | ||
+ | 2L | ||
+ | </source> | ||
+ | |||
+ | == Cadenas == | ||
+ | Inmutables. iterables. Cadenas de bytes y unicode. | ||
+ | <source lang="python" enclose="div"> | ||
+ | >>> nombre = 'Luis' | ||
+ | >>> nombre.upper() | ||
+ | 'LUIS' | ||
+ | >>> nombre | ||
+ | 'Luis' | ||
+ | >>> nombre[0] = 'l' | ||
+ | |||
+ | Traceback (most recent call last): | ||
+ | File "<pyshell#13>", line 1, in <module> | ||
+ | nombre[0] = 'l' | ||
+ | TypeError: 'str' object does not support item assignment | ||
+ | </source> | ||
+ | |||
+ | === Formato de cadenas === | ||
+ | <source lang="python"> | ||
+ | # viejo estilo | ||
+ | >>> "%s %s" %('hello', 'world') | ||
+ | 'hello world' | ||
+ | |||
+ | # Nuevo estilo. PEP 3101 | ||
+ | >>> "{0} {1}".format('hello', 'world') | ||
+ | 'hello world' | ||
+ | </source> | ||
+ | |||
+ | == Lectura interactiva == | ||
+ | <source lang="python" enclose="div" line="GESHI_FANCY_LINE_NUMBERS" highlight="3"> | ||
+ | nombre = raw_input('Introduzca su nombre: ') | ||
+ | edad = raw_input('Introduzca la edad: ') | ||
+ | edad = int(edad) | ||
+ | </source> | ||
+ | == Control de flujo == | ||
+ | === if === | ||
+ | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | edad = int(raw_input('Introduce tu edad: ')) | ||
+ | if edad < 18: | ||
+ | print 'Menor de edad' | ||
+ | else: | ||
+ | print 'Mayor de edad' | ||
+ | </source> | ||
+ | No hay instrucción '''switch''' | ||
+ | |||
+ | === for === | ||
+ | <source lang="python" enclose="div"> | ||
+ | >>> for letra in 'Me llamo Luis': | ||
+ | print letra, | ||
+ | |||
+ | M e l l a m o L u i s | ||
+ | </source> | ||
+ | |||
+ | {{Tip|Evitad estilo '''java'''}} | ||
+ | <source lang="python"> | ||
+ | animals = ["cat", "dog", "bird"] | ||
+ | for index in range(len(animals)): | ||
+ | print index, animals[index] | ||
+ | </source> | ||
+ | Mejor: | ||
+ | <source lang="python"> | ||
+ | for animal in animals: | ||
+ | print animal | ||
+ | # o si hace falta enumerar | ||
+ | for n, animal in enumerate(animals): | ||
+ | print n, animal | ||
+ | </source> | ||
+ | |||
+ | === range === | ||
+ | <source lang="python" enclose="div"> | ||
+ | >>> range(5, 10) | ||
+ | [5, 6, 7, 8, 9] | ||
+ | >>> range(0, 10, 3) | ||
+ | [0, 3, 6, 9] | ||
+ | >>> range(-10, -100, -30) | ||
+ | [-10, -40, -70] | ||
+ | </source> | ||
+ | |||
+ | Para repetir 10 veces algo: | ||
+ | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | for x in range(10): | ||
+ | print 'Hola' | ||
+ | </source> | ||
+ | |||
+ | === while === | ||
+ | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | while temperatura > 24: | ||
+ | ventilador_encendido | ||
+ | </source> | ||
+ | |||
+ | === break, continue, else === | ||
+ | <source lang="python" enclose="div"> | ||
+ | >>> for n in range(2, 10): | ||
+ | ... for x in range(2, n): | ||
+ | ... if n % x == 0: | ||
+ | ... print n, 'es igual a', x, '*', n/x | ||
+ | ... break | ||
+ | ... else: | ||
+ | ... # sigue el bucle sin encontrar un factor | ||
+ | ... print n, 'es un numero primo' | ||
+ | </source> | ||
+ | |||
+ | |||
+ | == Funciones == | ||
+ | === Definición === | ||
+ | * Nueva tabla de nombres | ||
+ | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | def al_cubo(num): | ||
+ | return num ** 3 | ||
+ | </source> | ||
+ | |||
+ | === Argumentos por defecto === | ||
+ | <source lang="python"> | ||
+ | def eleva(num, exp=2): | ||
+ | return num ** exp | ||
+ | </source> | ||
+ | |||
+ | ===Argumentos clave:valor === | ||
+ | <source lang="python"> | ||
+ | def ficha_empleado(nombre, nif, edad): | ||
+ | ... | ||
+ | ficha_empleado(nombre='Manuel', nif='123454P', edad=35) | ||
+ | |||
+ | </source> | ||
+ | |||
+ | ===Argumentos variables === | ||
+ | La sintaxis '''*args''' y '''**kwargs''' en la definición de las funciones se usa para pasar un número no fijo de argumentos a la función. Un asterisco simple se usa para pasar una lista de argumentos y el doble asterisco para pasar argumentos de tipo clave:valor (diccionario) | ||
+ | |||
+ | '''Usando *args''' | ||
+ | <source lang="python"> | ||
+ | >>> def test_argumentos_variables(farg, *args): | ||
+ | print 'arg. formal', farg | ||
+ | for arg in args: | ||
+ | print 'otro arg.', arg | ||
+ | |||
+ | >>> test_argumentos_variables('hola', 1, 'dos', 3) | ||
+ | arg. formal hola | ||
+ | otro arg. 1 | ||
+ | otro arg. dos | ||
+ | otro arg. 3 | ||
+ | </source> | ||
+ | '''Usando **kwargs''' | ||
+ | <source lang="python"> | ||
+ | >>> def test_argumentos_variables(farg, **kwargs): | ||
+ | print 'arg. formal', farg | ||
+ | for k in kwargs: | ||
+ | print 'otro arg con clave: %s: %s' % (k, kwargs[k]) | ||
+ | |||
+ | |||
+ | >>> test_argumentos_variables('hola', buenos="dias", temperatura=28) | ||
+ | arg. formal hola | ||
+ | otro arg con clave: temperatura: 28 | ||
+ | otro arg con clave: buenos: dias | ||
+ | </source> | ||
+ | |||
+ | '''Usando *args and **kwargs cuando llamamos a una función''' | ||
+ | <source lang="python"> | ||
+ | def test_var_args_call(arg1, arg2, arg3): | ||
+ | print "arg1:", arg1 | ||
+ | print "arg2:", arg2 | ||
+ | print "arg3:", arg3 | ||
+ | args = ("two", 3) | ||
+ | |||
+ | test_var_args_call(1, *args) | ||
+ | ''' | ||
+ | Resultado: | ||
+ | |||
+ | arg1: 1 | ||
+ | arg2: two | ||
+ | arg3: 3 | ||
+ | ''' | ||
+ | </source> | ||
+ | |||
+ | <source lang="python"> | ||
+ | def test_var_args_call(arg1, arg2, arg3): | ||
+ | print "arg1:", arg1 | ||
+ | print "arg2:", arg2 | ||
+ | print "arg3:", arg3 | ||
+ | kwargs = {"arg3": 3, "arg2": "two"} | ||
+ | |||
+ | test_var_args_call(1, **kwargs) | ||
+ | ''' | ||
+ | Resultado: | ||
+ | |||
+ | arg1: 1 | ||
+ | arg2: two | ||
+ | arg3: 3 | ||
+ | ''' | ||
+ | </source> | ||
+ | |||
+ | == Estructuras de datos == | ||
+ | === Listas === | ||
+ | Secuencias ordenadas. Dinámicas. Acceso por índice. Heterogéneas. Corchetes. | ||
+ | <source lang="python" line="GESHI_FANCY_LINE_NUMBERS" enclose="div"> | ||
+ | notas = [8, 7, 4.5, 6] | ||
+ | notas.append(9) | ||
+ | media = sum(notas)/len(notas) | ||
+ | print media # 6.9 | ||
+ | </source> | ||
+ | === Tuplas === | ||
+ | Estáticas. Paréntesis. | ||
+ | |||
+ | === Diccionarios === | ||
+ | <source lang="python"> | ||
+ | >>> letras = {} | ||
+ | >>> for l in 'supercalifragilisticoespialidoso': | ||
+ | ... letras[l] = letras.get('l', 0) + 1 | ||
+ | ... | ||
+ | >>> letras | ||
+ | {'a': 3, 'c': 3, 'e': 3, 'd': 4, 'g': 2, 'f': 2, 'i': 4, 'l': 3, 'o': 4, 'p': 3, 's': 4, 'r': 2, 'u': 1, 't': 3} | ||
+ | >>> letras.keys() | ||
+ | >>> letras.values() | ||
+ | >>> letras.items() | ||
+ | </source> | ||
+ | |||
+ | == Ficheros == | ||
+ | <source lang="python"> | ||
+ | |||
+ | # viejo estilo | ||
+ | fin = open("foo.txt") | ||
+ | for linea in fin: | ||
+ | # manipular linea | ||
+ | fin.close() | ||
+ | |||
+ | # mejor | ||
+ | with open('foo.txt') as fin: | ||
+ | for linea in fin: | ||
+ | # manipular linea | ||
+ | </source> | ||
+ | |||
+ | == Excepciones== | ||
+ | <source lang="python"> | ||
+ | try: | ||
+ | f = open("file.txt") | ||
+ | except IOError, e: | ||
+ | # tratar excepción | ||
+ | </source> | ||
+ | Más complejo: | ||
+ | <source lang="python"> | ||
+ | try: | ||
+ | # código con riesgo | ||
+ | except Exception, e: | ||
+ | # captura excepción | ||
+ | else: | ||
+ | # si no ha saltado ninguna excepción | ||
+ | finally: | ||
+ | # ejecuta al final | ||
+ | </source> | ||
+ | |||
+ | == Importar módulos == | ||
+ | <source lang="python"> | ||
+ | import math | ||
+ | from math import sin | ||
+ | import longname as ln | ||
+ | |||
+ | math.sqrt(9) | ||
+ | sin(30) | ||
+ | ln(2) | ||
+ | </source> | ||
+ | {{Lectura| | ||
+ | http://docs.python.org.ar/tutorial/modules.html#el-camino-de-busqueda-de-los-modulos | ||
+ | }} | ||
+ | |||
+ | == 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 | ||
+ | <source lang="python"> | ||
+ | print (123).__class__ | ||
+ | print zip.__class__ | ||
+ | print list.__class__ | ||
+ | import os ; print os.__class__ | ||
+ | </source> | ||
+ | |||
+ | Y todo objeto tiene una clase. | ||
+ | |||
+ | === Clase = Arquetipo del objeto. === | ||
+ | |||
+ | <source lang="python"> | ||
+ | |||
+ | class Estudiante(object): | ||
+ | def __init__(self, nombre, edad): | ||
+ | self.nombre = nombre | ||
+ | self.edad = edad | ||
+ | maria = Estudiante('María', 19) | ||
+ | print maria.nombre | ||
+ | </source> | ||
+ | |||
+ | ===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=== | ||
+ | <source lang="python"> | ||
+ | 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() | ||
+ | </source> | ||
+ | * 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"''' | ||
+ | <source lang="python"> | ||
+ | maria.edad += 1 | ||
+ | </source> | ||
+ | |||
+ | === Herencia=== | ||
+ | <source lang="python"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | * Si el padre necesitaba parámetros, hay que llamar a su método '''__init__''' | ||
+ | <source lang="python"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | === Métodos especiales === | ||
+ | <source lang="python"> | ||
+ | __init__(self, ...) | ||
+ | __new__(cls, args) | ||
+ | __del__(self) | ||
+ | __str__(self) | ||
+ | __cmp__(self, otro) | ||
+ | __len__(self) | ||
+ | __getitem__(self, key) | ||
+ | __setitem__(self, key, valor) | ||
+ | ... | ||
+ | </source> | ||
+ | |||
+ | <source lang="python"> | ||
+ | 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) | ||
+ | </source> | ||
+ | |||
+ | ===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). | ||
+ | <source lang="python"> | ||
+ | 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.' | ||
+ | </source> | ||
+ | Salida: | ||
+ | Hemos creado 3 objetos. | ||
+ | Soy el objeto Segundo de 3 objetos. | ||
+ | |||
+ | <source lang="python"> | ||
+ | class Objeto(object): | ||
+ | @classmethod | ||
+ | def metodo_de_clase(cls): | ||
+ | print "Invocado desde la clase %s " % cls | ||
+ | class ObjetoHijo(Objeto): | ||
+ | pass | ||
+ | </source> | ||
+ | Ejemplo de uso: | ||
+ | <source lang="python"> | ||
+ | >>> 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'> | ||
+ | </source> | ||
+ | == 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. |
Última revisión de 19:26 6 sep 2011
Contenido
- 1 ¿Python?
- 2 Peculiaridades
- 3 Ampliación
- 4 Echa un vistazo
- 5 Actividad
- 6 Recursos de la Web
- 7 Lectura
Puedes ver los contenidos en formato presentación: Inmersión I :: Inmersión II
¿Python?
|
Charla Python@Google: http://www.google.com/events/io/2011/sessions/python-google.html |
Instalación
Sitio de referencia: http://python.org/download/ En linux normalmente suele estar instalado el intérprete. Puedes usar el sistema de paquetes de tu distribución o instalar desde la fuente del programa (necesitas compilador). En Windows usa el instalador apropiado.
Guía de instalación y uso: http://docs.python.org/using/index.html (en inglés) |
Mi primer programa
Ejecutables linux
#!/usr/bin/env python
$ chmod +x hello.py $ ./hello.py
Herramientas para programar
Listado completo de recursos disponibles: http://wiki.python.org/moin/IntegratedDevelopmentEnvironments |
Nosotros vamos a ir utilizando diferentes entornos de desarrollo a lo largo del curso.
El intérprete
Hola, mundo
>>> impuesto = 12.5 / 100
>>> precio = 100.50
>>> precio * impuesto
12.5625
>>> precio + _
113.0625
>>> round(_, 2)
113.06
Un programa que hace algo
- # No declaramos variables, ponemos nombres a objetos
- coches = 100
- capacidad_coche = 4.0
- conductores = 30
- pasajeros = 90
- coches_no_conducidos = coches - conductores
- coches_conducidos = conductores
- capacidad_real = coches_conducidos * capacidad_coche
- media_pasajeros_coche = pasajeros / coches_conducidos
- print "Hay", coches, "coches disponibles."
- print "Tenemos sólo ", conductores, "conductores disponibles."
- print "Habrá", coches_no_conducidos, "coches vacíos hoy."
- print "Podemos transportar", capacidad_real, "personas hoy."
- print "Tenemos", pasajeros, "pasajeros para transportar."
- print "Tenemos que poner una media de", media_pasajeros_coche, "por coche hoy."
Sobre el estilo
http://docs.python.org.ar/tutorial/controlflow.html#intermezzo-estilo-de-codificacion
- minúsculas
- guiones bajo_entre_palabras
- no pueden comenzar con números
- ni se pueden usar palabras reservadas (file, assert, class, def
Introspección
- dir(<objeto>)
- help(<objeto>.<metodo>)
Operaciones con números
Las básicas como en otros lenguajes. Operaciones matemáticas import math. Observa:
>>> 5/2
2
>>> 5/2.
2.5
# Conversión automática
>>> 10 ** 10
10000000000L
Casting
>>> num = '2.3' >>> float(num) 2.3 >>> int('2') 2 >>> long('2') 2L
Cadenas
Inmutables. iterables. Cadenas de bytes y unicode.
>>> nombre.upper()
'LUIS'
>>> nombre
'Luis'
>>> nombre[0] = 'l'
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
nombre[0] = 'l'
TypeError: 'str' object does not support item assignment
Formato de cadenas
# viejo estilo >>> "%s %s" %('hello', 'world') 'hello world' # Nuevo estilo. PEP 3101 >>> "{0} {1}".format('hello', 'world') 'hello world'
Lectura interactiva
- nombre = raw_input('Introduzca su nombre: ')
- edad = raw_input('Introduzca la edad: ')
- edad = int(edad)
Control de flujo
if
- edad = int(raw_input('Introduce tu edad: '))
- if edad < 18:
- print 'Menor de edad'
- else:
- print 'Mayor de edad'
No hay instrucción switch
for
print letra,
M e l l a m o L u i s
animals = ["cat", "dog", "bird"] for index in range(len(animals)): print index, animals[index]
Mejor:
for animal in animals: print animal # o si hace falta enumerar for n, animal in enumerate(animals): print n, animal
range
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
Para repetir 10 veces algo:
- for x in range(10):
- print 'Hola'
while
- while temperatura > 24:
- ventilador_encendido
break, continue, else
... for x in range(2, n):
... if n % x == 0:
... print n, 'es igual a', x, '*', n/x
... break
... else:
... # sigue el bucle sin encontrar un factor
... print n, 'es un numero primo'
Funciones
Definición
- Nueva tabla de nombres
- def al_cubo(num):
- return num ** 3
Argumentos por defecto
def eleva(num, exp=2): return num ** exp
Argumentos clave:valor
def ficha_empleado(nombre, nif, edad): ... ficha_empleado(nombre='Manuel', nif='123454P', edad=35)
Argumentos variables
La sintaxis *args y **kwargs en la definición de las funciones se usa para pasar un número no fijo de argumentos a la función. Un asterisco simple se usa para pasar una lista de argumentos y el doble asterisco para pasar argumentos de tipo clave:valor (diccionario)
Usando *args
>>> def test_argumentos_variables(farg, *args): print 'arg. formal', farg for arg in args: print 'otro arg.', arg >>> test_argumentos_variables('hola', 1, 'dos', 3) arg. formal hola otro arg. 1 otro arg. dos otro arg. 3
Usando **kwargs
>>> def test_argumentos_variables(farg, **kwargs): print 'arg. formal', farg for k in kwargs: print 'otro arg con clave: %s: %s' % (k, kwargs[k]) >>> test_argumentos_variables('hola', buenos="dias", temperatura=28) arg. formal hola otro arg con clave: temperatura: 28 otro arg con clave: buenos: dias
Usando *args and **kwargs cuando llamamos a una función
def test_var_args_call(arg1, arg2, arg3): print "arg1:", arg1 print "arg2:", arg2 print "arg3:", arg3 args = ("two", 3) test_var_args_call(1, *args) ''' Resultado: arg1: 1 arg2: two arg3: 3 '''
def test_var_args_call(arg1, arg2, arg3): print "arg1:", arg1 print "arg2:", arg2 print "arg3:", arg3 kwargs = {"arg3": 3, "arg2": "two"} test_var_args_call(1, **kwargs) ''' Resultado: arg1: 1 arg2: two arg3: 3 '''
Estructuras de datos
Listas
Secuencias ordenadas. Dinámicas. Acceso por índice. Heterogéneas. Corchetes.
- notas = [8, 7, 4.5, 6]
- notas.append(9)
- media = sum(notas)/len(notas)
- print media # 6.9
Tuplas
Estáticas. Paréntesis.
Diccionarios
>>> letras = {} >>> for l in 'supercalifragilisticoespialidoso': ... letras[l] = letras.get('l', 0) + 1 ... >>> letras {'a': 3, 'c': 3, 'e': 3, 'd': 4, 'g': 2, 'f': 2, 'i': 4, 'l': 3, 'o': 4, 'p': 3, 's': 4, 'r': 2, 'u': 1, 't': 3} >>> letras.keys() >>> letras.values() >>> letras.items()
Ficheros
# viejo estilo fin = open("foo.txt") for linea in fin: # manipular linea fin.close() # mejor with open('foo.txt') as fin: for linea in fin: # manipular linea
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.