Copyright (c) 2003 Eduardo Ferro Aldama bajo GNU FDL
Pretendo dar unas nociones básicas del uso de este lenguaje para desarrollo de aplicaciones orientadas a objetos. Dado que la sintaxis es muy sencilla y fácil de leer (como vereis parece pseudocódigo) vamos a pasar directamente a ver ejemplos de como podemos usarlo.
class Barrio:
def __init__(self, nombre, numeroHabitantes):
self.__nombre = nombre
self.__numeroHabitantes = numeroHabitantes
def getNombre(self):
return self.__nombre
def getNumeroHabitantes(self):
return self.__numeroHabitantes
El código anterior define la clase Barrio que esta compuesta por
tres metodos, el constructor, getNombre y getNumeroHabitantes.
Los constructores en Python tienen que tener el nombre __init__, en este caso
nuestro constructor crea dos atributos (__nombre y __numeroHabitantes) que
utiliza para almacenar los parametros pasados.
Todos los métodos deben tener como primer parametro la palabra reservada
"self" que representa la instancia de la clase actual (igual que la palabra
"this" en C++ o Java). En Python la palabra "self" es obligatoria y siempre
hay que utilizarla para acceder a los atributos o incluso para llamar a un
método de nuestra misma clase.
Los otros dos métodos definidos son simplemente métodos de acceso para los atributos de la clase.
barrioNorte = Barrio("Norte", 10000)
barrioSur = Barrio("Sur", 4000)
Como podemos ver para crear instancias de una clase, es decir objetos basta
con llamar al nombre de la clase como si se tratase de una función y asignar
el resultado a una variable o atributo.
Como habeis podido ver en Python no es necesario declarar las variables, o atributos antes de poder usarlos, basta con asignar algo a una variable. Ademas es debilmente tipado por lo que una variable puede contener cualquier tipo. Esto implica que tenemos que tener mucho cuidado de que parametros pasamos a un método, puesto que puede que el tipo del parametro que enviemos no sea el que el método espera por lo que se produciría un error en ejecución.
#!/usr/bin/env python
class Barrio:
def __init__(self, nombre, numeroHabitantes):
# Asignamos valores a los atributos
self.__nombre = nombre
self.__numeroHabitantes = numeroHabitantes
def getNombre(self):
return self.__nombre
def getNumeroHabitantes(self):
return self.__numeroHabitantes
def main():
# creamos dos objetos de la clase
# Barrio
barrioNorte = Barrio("Norte", 10000)
barrioSur = Barrio("Sur", 4000)
# Imprimimos el nombre asignado a los
# dos barrios
print barrioNorte.getNombre()
print barrioSur.getNombre()
main()
Si copiamos el codigo anterior en un fichero (por ejemplo Barrio.py)
y le damos permisos de ejecucion (chmod u+x nombreFichero) podemos
ejecutar el fichero desde la linea de comandos de linux como si se
tratase de un script de shell. La primera linea define que interprete
se debe usar, el resto del ejemplo es el codigo Python a interpretar.
En este ejemplo hemos introducido algunos conceptos nuevos:
Por una parte hemos introducido comentarios, python considera comentario
desde el caracter "#" hasta el final de la línea.
Por otra parte hemos definido una función llamada main a la que llamamos al
final del fichero.
Python interpreta el fichero de arriba a abajo y ejecuta todo el código que
encuentre fuera de funciones o clases. En este caso el único código que se
encuentra fuera de una función o de la definición de una clases es la llamada
a la función main por lo que cuando interpretemos este fichero se ejecutará
la función main.
La función inicial se suele llamar main, pero no es obligado usar
ese nombre.
class Barrio:
"""clase para representar un barrio,
permitiendo la gestion del nombre del
barrio y del numero de habitantes del mismo"""
def __init__(self, nombre, numeroHabitantes):
"""Constructor de la clase Barrio.
Almacena el nombre del barrio
y el numero de habitantes"""
# Asignamos valores a los atributos
self.__nombre = nombre
self.__numeroHabitantes = numeroHabitantes
def getNombre(self):
"""Devuelve el nombre del barrio"""
return self.__nombre
def getNumeroHabitantes(self):
"""Devuelve el numero de habitantes
del barrio"""
return self.__numeroHabitantes
# Lista vacia
l = []
# Lista de tres elementos
# los dos primeros numéricos y el último
# de tipo cadena
l = [1, 2, 'foo']
l.append(2) # Añadimos un elemento
l.append('bar') # Añadimos otro
l.remove(2) # Eliminamos el primer 2 de la lista
# l = [1, 'foo', 2, 'bar']
# Obtenemos número de elementos
numeroElementos = len(l)
# recorremos la lista
for elemento in l:
print elemento
# Accedemos al primer elemento
elemento = l[0]
# Tupla vacia
t = ()
# Tupla de tres elementos
# los dos primeros numéricos y el último
# de tipo cadena
t = (1, 2, 'foo')
# Obtenemos número de elementos
numeroElementos = len(t)
# recorremos la tupla
for elemento in t:
print elemento
# Accedemos al primer elemento
elemento = t[0]
# Diccionario vacio
dic = {}
# Diccionario con dos entradas
# con distintos tipos de claves y
# de valores
doc = {2: 'valor2', 'clave': 5}
# Añadimos un elemento
dic[3] = 'valor3'
# Obtenemos un elmento
valor = dic[2]
# obtenemos la lista de claves
listaClaves = dic.keys()
# obtenemos la lista de valores
listaValores = dic.values()
# Ejemplo 1
if barrio1.getNombre() == "Norte":
print "Tratamiento barrio Norte"
# Ejemplo 2
if barrio1.getNombre() == "Norte":
print "Tratamiento barrio Norte"
else:
print "Tratmiento para otros barrios"
# Ejemplo 3
if barrio1.getNombre() == "Norte":
print "Tratamiento barrio Norte"
elif barrio1.getNombre() == "Sur":
print "Tratamiento barrio Sur"
else:
print "Ni uno ni otro"
# Ejemplo 4
listaNombres = ['Nombre1', 'Nombre2', 'Nombre3']
for nombre in listaNombres:
print nombre
# Ejemplo 5
for numero in range(0, 5):
print numero
# Ejemplo 6
encontradoFin = 0
n = 0
numeroIteraciones = 5
while not encontradoFin:
if n == numeroIteraciones:
encontradoFin = 1
else:
print "No encontrado Fin"
n = n + 1
print "Encontrado fin"
Para los ejemplos del 1 al 3 debemos suponer que barrio1 es un objeto
de la clase Barrio. Lo único que cabe destacar en estos primeros
ejemplos es que en python no existe la estructura switch por lo que
para encadenar diferentes opciones se usa la estructura del ejemplo 3.
#!/usr/bin/env python
class Vehiculo:
def __init__(self, ruedas):
self.__ruedas = ruedas
def tocaBocina(self):
print "Beep, Beep!!!"
class Coche(Vehiculo):
def __init__(self, modelo):
# llamamos al constructor de nuestro
# padre
Vehiculo.__init__(self, 4)
self.__modelo = modelo
def tocaBocina(self):
print "Piiiiiii!!!"
class Bicicleta(Vehiculo):
def __init__(self):
# llamamos al constructor de nuestro
# padre
Vehiculo.__init__(self, 2)
def tocaBocina(self):
print "Ring, Ring!!!"
def main():
listaVehiculos = []
listaVehiculos.append(Coche("r9"))
listaVehiculos.append(Vehiculo(3))
listaVehiculos.append(Bicicleta())
listaVehiculos.append(Coche("p205"))
for vehiculo in listaVehiculos:
vehiculo.tocaBocina()
main()
El ejemplo anterior define las clases Vehiculo, Coche y
Bicicleta. La primera clase sirve como base para Coche y
Bicicleta. En Python al definir una clase después del nombre de la
clase se pone entre parentesis la clase o clases de las que hereda. Se
permite la herencia multiple aunque es un recurso que se debe usar con
cuidado.
Las tres clases definen un mismo método llamado tocaBocina, de forma
que las clases derivadas sobreescriben el método de la base. Cuando el
interprete necesita llamar a un método de un objeto busca la definicion del
método en todo el árbol de herencia de la clase, empezando desde la clase
especifica y subiendo por los antecesores. Esto significa que si se
necesitase llamar al método tocaBocina en un objeto de una clase que
no hubiese definido ese método, se intentaria buscar el método en cada uno de
los antecesores de la clase, en caso de que ninguno de los ancestros hubiese
definido ese método se produciría un error de ejecución.
Este tipo de comportamiento permite usar de forma polimórfica los objetos. Un
ejemplo de esto es el recorrido de la lista de vehiculos donde por cada uno
llamamos al método tocaBocina sin tener que preocuparnos de que tipo
es cada uno de los vehiculos. Como podemos suponer el resultado de la
ejecución del ejemplo es:
Piiiiiii!!! Beep, Beep!!! Ring, Ring!!! Piiiiiii!!!
En Python todos los métodos y atributos son publicos por defecto, para hacerlos privados debemos hacer que comiencen por __. En realidad esto no los hace exactamente privados pero impide el uso normal de los mismos desde fuera de la clase donde se declaran
Si quieres ponerte en contacto conmigo:
eferro@inicia.es