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

De WikiEducator
Saltar a: navegación, buscar
(Métodos estáticos)
(Instalación)
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)

Revisión de 19:05 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'>