Diferencia entre revisiones de «Curso Python DGA 2011/inmersion python/contenidos»

De WikiEducator
Saltar a: navegación, buscar
(Argumentos variables)
(=Instalar virtualenv)
 
(10 revisiones intermedias por el mismo usuario no mostrado)
Línea 25: Línea 25:
  
 
== Instalación ==
 
== Instalación ==
<br />
+
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 249: Línea 252:
 
ficha_empleado(nombre='Manuel', nif='123454P', edad=35)
 
ficha_empleado(nombre='Manuel', nif='123454P', edad=35)
  
def ficha_empleado(nombre, *args, **kargs):
 
    ...
 
</source>
 
 
===Argumentos clave:valor ===
 
<source lang="python">
 
def ficha_empleado(nombre, nif, edad):
 
    ...
 
ficha_empleado(nombre='Manuel', nif='123454P', edad=35)
 
 
</source>
 
</source>
  
 
===Argumentos variables ===
 
===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)
 
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'''
 
'''Usando *args'''
 
<source lang="python">
 
<source lang="python">
Línea 524: Línea 519:
 
     print sorted(estudiantes)
 
     print sorted(estudiantes)
 
</source>
 
</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



Icon present.gif
Tip:

Puedes ver los contenidos en formato presentación: Inmersión I :: Inmersión II


¿Python?



Icon key points.gif

Peculiaridades

  • Interpretado, pero compilado a bytecode.
  • Tipado dinámico, pero fuertemente tipado
  • Multiplataforma
  • Orientado a objetos
  • Sintáxis sencilla pero muy robusta.
  • Fácil de escribir, de leer y de mantener.
  • Muy potente (baterías incluidas) y gran soporte.
  • Más ... para abrir el apetito: http://docs.python.org.ar/tutorial/appetite.html
  • Importancia creciente de python en la educación.







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.



Icon inter.gif

Echa un vistazo

Guía de instalación y uso: http://docs.python.org/using/index.html (en inglés)




Icon activity.jpg

Actividad

  • Comprueba que está instalado python en el sistema (¿qué versión?)
  • Si no está instalado, descarga e instala la última versión estable de la rama 2.x





Mi primer programa

Ejecutables linux

#!/usr/bin/env python
$ chmod +x hello.py
$ ./hello.py

Herramientas para programar



Icon inter.gif

Recursos de la Web

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

>>> print "Hola, mundo"
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

  1. # No declaramos variables, ponemos nombres a objetos
  2. coches = 100
  3. capacidad_coche = 4.0
  4. conductores = 30
  5. pasajeros = 90
  6. coches_no_conducidos = coches - conductores
  7. coches_conducidos = conductores
  8. capacidad_real = coches_conducidos * capacidad_coche
  9. media_pasajeros_coche = pasajeros / coches_conducidos
  10.  
  11. print "Hay", coches, "coches disponibles."
  12. print "Tenemos sólo ", conductores, "conductores disponibles."
  13. print "Habrá", coches_no_conducidos, "coches vacíos hoy."
  14. print "Podemos transportar", capacidad_real, "personas hoy."
  15. print "Tenemos", pasajeros, "pasajeros para transportar."
  16. 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
Icon present.gif
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:

# Cuidado!
>>> 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 = '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

Formato de cadenas

# viejo estilo 
>>> "%s %s" %('hello', 'world')
'hello world'
 
# Nuevo estilo. PEP 3101
>>> "{0} {1}".format('hello', 'world')
'hello world'

Lectura interactiva

  1. nombre = raw_input('Introduzca su nombre: ')
  2. edad = raw_input('Introduzca la edad: ')
  3. edad = int(edad)

Control de flujo

if

  1. edad = int(raw_input('Introduce tu edad: '))
  2. if edad < 18:
  3.     print 'Menor de edad'
  4. else:
  5.     print 'Mayor de edad'

No hay instrucción switch

for

>>> for letra in 'Me llamo Luis':
        print letra,

M e   l l a m o   L u i s
Icon present.gif
Tip: Evitad estilo java


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

>>> range(5, 10)
[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:

  1. for x in range(10):
  2.     print 'Hola'

while

  1. while temperatura > 24:
  2.     ventilador_encendido

break, continue, else

>>> 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'


Funciones

Definición

  • Nueva tabla de nombres
  1. def al_cubo(num):
  2.     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.

  1. notas = [8, 7, 4.5, 6]
  2. notas.append(9)
  3. media = sum(notas)/len(notas)
  4. 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

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.