Versión original en inglés de J.R. Johansson (robert@riken.jp) http://jrjohansson.github.io/.
Traducido/Adaptado por G.F. Rubilar.
La última versión de estos notebooks de IPython está disponible en http://github.com/gfrubi/clases-python-cientifico.
La última versión del original (en inglés) de estos notebooks de IPython está disponible en http://github.com/jrjohansson/scientific-python-lectures.
Los otros notebooks de esta serie están listados en http://jrjohansson.github.com.
El código Python es usualmente almacenado en archivos de texto con entensión ".py
":
miprograma.py
Se asume que cada línea de un archivo de programa en Python es una sentencia Python, o parte de una sentencia.
#
(opcionalmente precedida por un número arbitrario de caracteres de espacio en blanco, es decir, tabs y espacios. Las líneas de comentarios son usualmente ignoradas por el intérprete Python.Para ejecutar nuestro programa Python desde la línea de comando usamos:
$ python miprograma.py
En sistemas UNIX es común definir la ruta al intérprete en la primera línea del programa (note que ésta es una línea de comentarios en lo que respecta al intérprete Python):
#!/usr/bin/env python
Si hacemos esto, y adicionalmente configuramos el archivo para que sea ejecutable, podemos correr el programa usando:
$ miprograma.py
ls scripts/hola-mundo*.py
scripts/hola-mundo-en-sueco.py scripts/hola-mundo.py
cat scripts/hola-mundo.py
#!/usr/bin/env python print("Hola mundo!")
!python scripts/hola-mundo.py
Hola mundo!
La codificación estándar de caracteres es la ASCII, pero podemos usar cualquier otra codificación, por ejemplo UTF-8. Para especificar que usamos UTF-8 incluimos la línea especial
# -*- coding: UTF-8 -*-
al comienzo del archivo.
cat scripts/hola-mundo-en-sueco.py
#!/usr/bin/env python # -*- coding: UTF-8 -*- print("Hej världen!")
!python scripts/hola-mundo-en-sueco.py
Hej världen!
Aparte de estas dos líneas opcionales al comienzo de un archivo Python, no se requiere de otro código adicional para inicializar un programa. Por otro lado, en la versión 3 de Python ya no es necesario agregar código extra alguno.
Este archivo - un notebook IPython - no sigue el patrón estándar de código Python en un archivo de texto. En su lugar, un notebook IPython es almacenado como un archivo en el formato JSON. La ventaja es que podemos mezclar texto formateado, código Python, y código de salida. Esto requiere estar ejecutando un servidor de notebook IPython, y por eso este tipo de archivo no es un programa Python independiente como se describió antes. Aparte de eso, no hay diferencia entre el código Python en un archivo de programa o en un notebook IPython.
Los nombres de las variables en Python pueden contener los caracteres a-z
, A-Z
, 0-9
y algunos caracteres especiales como _
. Los nombres de variables normales deben comenzar con una letra.
Por convención, los nombres de las variables comienzan con letra minúscula, mientras que los nombres de las clases comienzan con una letra mayúscula.
Además, existen algunos palabras claves Python que no pueden ser usados como nombres de variables. Éstas son:
and, as, assert, break, class, continue, def, del, elif, else, except,
exec, finally, for, from, global, if, import, in, is, lambda, not, or,
pass, print, raise, return, try, while, with, yield
Nota: Atención con la palabra lambda
, que podría fácilmente ser un nombre de variable natural en un programa científico. Sin embargo, como es una palabra clave, no puede ser usado como nombre de una variable.
El operador para asignar valores en Python es el signo igual (=
). Python es un lenguage de escritura dinámica, de modo que no necesitamos especificar el tipo de una variable cuando la creamos.
Al asignar un valor a una variable nueva se crea esa variable:
# asignaciones de variables
x = 1.0
mi_variable = 12.2
Aunque no se especifique explícitamente, cada variable sí tiene un tipo asociada a ella. El tipo es extraido del valor que le fue asignado.
type(x)
float
Si asignamos un nuevo valor a una variable, su tipo puede cambiar.
x = 1
type(x)
int
Si tratamos de unsar una variable que no ha sido definida obtenemo un mensaje de error (NameError
):
print(y)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-18-36b2093251cd> in <module>() ----> 1 print(y) NameError: name 'y' is not defined
# enteros
x = 1
type(x)
int
# flotantes
x = 1.0
type(x)
float
# booleanos
b1 = True
b2 = False
type(b1)
bool
# números complejos: note que se usa `j` para especificar la parte imaginaria
x = 1.0 - 1.0j
type(x)
complex
print(x)
(1-1j)
print(x.real, x.imag)
(1.0, -1.0)
El módulo types
contiene definiciones de nombres de tipo que pueden ser usadas para testear si las variables son de un cierto tipo:
import types
# imprime todos los tipos definidos en el módulo `types`
print(dir(types))
['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
x = 1.0
# verifica si la variable x es flotante
type(x) is float
True
# verifica si la variable x es un entero
type(x) is int
False
Podemos también usar el método isinstance
para testear tipos de variables:
isinstance(x, float)
True
x = 1.5
print(x, type(x))
(1.5, <type 'float'>)
x = int(x)
print(x, type(x))
(1, <type 'int'>)
z = complex(x)
print(z, type(z))
((1+0j), <type 'complex'>)
x = float(z)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-33-e719cc7b3e96> in <module>() ----> 1 x = float(z) TypeError: can't convert complex to float
Un número complejo no puede ser convertido a un número flotante o a un entero. Necesitamos usar z.real
, o bien z.imag
, para extraer la parte que deseamos del número complejo z:
y = bool(z.real)
print(z.real, " -> ", y, type(y))
y = bool(z.imag)
print(z.imag, " -> ", y, type(y))
(1.0, ' -> ', True, <type 'bool'>) (0.0, ' -> ', False, <type 'bool'>)
La mayoría de los operadores y las comparaciones en Python funcionan como one esperaría:
+
, -
, *
, /
, //
(división entera), '**' potencia1 + 2, 1 - 2, 1 * 2, 1 / 2
(3, -1, 2, 0)
1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0
(3.0, -1.0, 2.0, 0.5)
# División entera de dos númenos flotantes
3.0 // 2.0
1.0
# Atención! El operador de potencia en Python no es ^, sino **
2 ** 2
4
and
, not
, or
.True and False
False
not False
True
True or False
True
>
, <
, >=
(mayor o igual), <=
(menor o igual), ==
igualdad, es
identico.2 > 1, 2 < 1
(True, False)
2 > 2, 2 < 2
(False, False)
2 >= 2, 2 <= 2
(True, True)
# igualdad
[1,2] == [1,2]
True
# ¿objetos identicos?
l1 = l2 = [1,2]
l1 is l2
True
s = "Hola mundo"
type(s)
str
# longitud de la cadena: el número de caracteres que contiene
len(s)
10
# reemplaza una subcadena de una cadena por cadena
s2 = s.replace("mundo", "universo")
print(s2)
Hola universo
Podemos aislar un carácter en una cadena usando []
:
s[0]
'H'
Atención usuarios de MATLAB: el indexado comienza en 0!
Podemos extraer una parte de una cadena usando la sintaxis [desde:hasta]
, que extrae caracteres entre los índices desde
y hasta
:
s[0:5]
'Hola '
Si omitimos desde
o bien hasta
de [desde:hasta]
, por defecto se entiende que se refiere al comienzo y/o al fin de la cadena, respectivamente:
s[:5]
'Hola '
s[6:]
'undo'
s[:]
'Hola mundo'
Podemos también definir el tamaño del paso usando la sintaxis [desde:hasta:paso]
(el valor por defecto de paso
es 1, como ya vismo):
s[::1]
'Hola mundo'
s[::2]
'Hl ud'
Esta técnica es llamada slicing ("rebanado"). Puede leer más sobre la sintaxis aquí http://pyspanishdoc.sourceforge.net/lib/built-in-funcs.html y aquí (en inglés) http://docs.python.org/release/2.7.3/library/functions.html?highlight=slice#slice
Python tiene un rico conjunto de funciones para procesar texto. Ver por ejemplo http://docs.python.org/2/library/string.html (en inglés) para más información.
print("uno", "dos", "tres") # El comando print puede desplegar varias cadenas
('uno', 'dos', 'tres')
print("uno", 1.0, False, -1j) # El comendo print convierte todos los argumentos a cadenas
('uno', 1.0, False, -1j)
print("uno" + "dos" + "tres") # cadenas "sumadas" con + son contatenadas sin espacio entre ellas
unodostres
print("valor = %f" % 1.0) # podemos usar formateo de cadenas en el estilo del lenguaje C
valor = 1.000000
# este formateo crea una cadena
s2 = "valor1 = %.2f. valor2 = %d" % (3.1415, 1.5)
print(s2)
valor1 = 3.14. valor2 = 1
# forma alternativa, más intuitiva para formatear una cadena
s3 = 'valor1 = {0}, valor2 = {1}'.format(3.1415, 1.5)
print(s3)
valor1 = 3.1415, valor2 = 1.5
Listas son muy similares a las cadenas, excepto que cada elemento puede ser de un tipo diferente.
La sintaxis para crear listas en Python es [..., ..., ...]
:
l = [1,2,3,4]
print(type(l))
print(l)
<type 'list'> [1, 2, 3, 4]
Podemos usar las mismas técnicas de "rebanado" que usamos en el caso de cadenas para manipular listas:
print(l)
print(l[1:3])
print(l[::2])
[1, 2, 3, 4] [2, 3] [1, 3]
Atención usuarios de MATLAB: el indexado comienza en 0!
l[0]
1
Los elementos en una lista no requieren ser del mismo tipo:
l = [1, 'a', 1.0, 1-1j]
print(l)
[1, 'a', 1.0, (1-1j)]
Las listas en Python pueden ser inhomogéneas y arbitrariamente anidadas:
lista_anidada = [1, [2, [3, [4, [5]]]]]
lista_anidada
[1, [2, [3, [4, [5]]]]]
Las listas juegan un rol muy importante en Python y son, por ejemplo, usadas en bucles y otras estructuras de control de flujo (discutidas más abajo). Existan muchas funciones convenientes para generar listas de varios tipos, por ejemplo la función range
:
desde = 10
hasta = 30
paso = 2
range(desde, hasta, paso)
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
# en Python 3 range genera un interador, que puede ser convertido a una lista usando 'list(...)'. Esto no tiene efecto en Python 2
list(range(desde, hasta, paso))
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
list(range(-10, 10))
[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
s
'Hola mundo'
# convierte una cadena a una lista, por conversión de tipo:
s2 = list(s)
s2
['H', 'o', 'l', 'a', ' ', 'm', 'u', 'n', 'd', 'o']
# ordenando listas
s2.sort()
print(s2)
[' ', 'H', 'a', 'd', 'l', 'm', 'n', 'o', 'o', 'u']
# crea una nueva lista vacía
l = []
# agrega un elemento usando `append`
l.append("A")
l.append("d")
l.append("d")
print(l)
['A', 'd', 'd']
Podemos modificar listas asignando nuevos valores a los elementos de la lista. En lenguaje técnico se dice que la lista es mutable.
l[1] = "p"
l[2] = "p"
print(l)
['A', 'p', 'p']
l[1:3] = ["d", "d"]
print(l)
['A', 'd', 'd']
Insertar un elemento en una posición específica insert
l.insert(0, "i")
l.insert(1, "n")
l.insert(2, "s")
l.insert(3, "e")
l.insert(4, "r")
l.insert(5, "t")
print(l)
['i', 'n', 's', 'e', 'r', 't', 'A', 'd', 'd']
Eliminar el primer elemento con un valor específico usando 'remove'
l.remove("A")
print(l)
['i', 'n', 's', 'e', 'r', 't', 'd', 'd']
Eliminar un elemento en una posición específica usando del
:
Puede introducir help(list)
para más detalles, o leer la documentación en la red
Tuplas son similares a las listas, excepto que ellas no pueden ser modificadas una vez creadas, es decir, son inmutables.
En Python, las tuplas son creadas usando la sintaxis (..., ..., ...)
, o incluso ..., ...
:
punto = (10, 20)
print(punto, type(punto))
((10, 20), <type 'tuple'>)
punto = 10, 20
print(punto, type(punto))
((10, 20), <type 'tuple'>)
Podemos separar una tupla asignandola a una lista de variables separadas por coma:
x, y = punto
print("x =", x)
print("y =", y)
('x =', 10) ('y =', 20)
Si intentamos asignar un nuevo valor a un elemento de una tupla obtenemos un error:
punto[0] = 20
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-83-4e812ab96337> in <module>() ----> 1 punto[0] = 20 TypeError: 'tuple' object does not support item assignment
Dictionarios son también como listas, excepto que cada elemento es un par clave-valor. La sintaxsis de los diccionarios es {clave1 : valor1, ...}
:
parametros = {"parametro1" : 1.0,
"parametro2" : 2.0,
"parametro3" : 3.0,}
print(type(parametros))
print(parametros)
<type 'dict'> {'parametro1': 1.0, 'parametro3': 3.0, 'parametro2': 2.0}
print("parametro1 = " + str(parametros["parametro1"]))
print("parametro2 = " + str(parametros["parametro2"]))
print("parametro3 = " + str(parametros["parametro3"]))
parametro1 = 1.0 parametro2 = 2.0 parametro3 = 3.0
parametros["parametro1"] = "A"
parametros["parametro2"] = "B"
# agrega una nueva entrada
parametros["parametro4"] = "D"
print("parametro1 = " + str(parametros["parametro1"]))
print("parametro2 = " + str(parametros["parametro2"]))
print("parametro3 = " + str(parametros["parametro3"]))
print("parametro4 = " + str(parametros["parametro4"]))
parametro1 = A parametro2 = B parametro3 = 3.0 parametro4 = D
La sintaxis Python para la ejecución condicional de código usa las palabras clave if
, elif
(else if), else
:
afirmacion1 = False
afirmacion2 = False
if afirmacion1:
print("afirmacion1 es verdadera")
elif afirmacion2:
print("afirmacion2 es verdadera")
else:
print("afirmacion1 y afirmacion2 son falsas")
afirmacion1 y afirmacion2 son falsas
Aquí encontramos por primera un aspecto pecular e inusual del lenguaje Python: Los bloques del programa son definidos por su nivel de indentación (la cantidad de espacio antes de cada linea).
Compare con el código equivalente en C:
if (afirmacion1)
{
printf("afirmacion1 es verdadera\n");
}
else if (afirmacion2)
{
printf("afirmacion1 es verdadera\n");
}
else
{
printf("afirmacion1 y afirmacion2 son falsas\n");
}
En C los bloques son definidos por los paréntesis llaves {
y }
. El nivel de indentación (espacio en blanco antes del código) no importa (es completamente opcional).
En Python, la extensión de un bloque de código es definido por el nivel de indentación (usualmente un tab o cuatro espacios en blanco). Esto significa que debemos ser cuidados@s de indentar nuestro código correctamente, de lo contrario tendremos errores de sintaxis.
Ejemplos:
afirmacion1 = afirmacion2 = True
if afirmacion1:
if afirmacion2:
print("tanto afirmacion1 como afirmacion2 son verdaderas")
tanto afirmacion1 como afirmacion2 son verdaderas
# Mala indentación!
if afirmacion1:
if afirmacion2:
print("tanto afirmacion1 como afirmacion2 son verdaderas") # esta línea está mal indentada
File "<ipython-input-89-6f069ee062b2>", line 4 print("tanto afirmacion1 como afirmacion2 son verdaderas") # esta línea está mal indentada ^ IndentationError: expected an indented block
afirmacion1 = False
if afirmacion1:
print("afirmacion1 es verdadera")
print("aun estamos dentro del bloque if")
if afirmacion1:
print("afirmacion1 es verdadera")
print("ahora estamos fuera del bloque")
En Python, los ciclos (loops) puede ser programados de varias maneras diferentes. La forma más común es usando un cicle for
, que se usa junto con objetos iterables, como por ejemplos las listas. La sintaxis básica es:
Ciclos for
:
for x in [1,2,3]:
print(x)
1 2 3
El ciclo for
itera sobre los elementos de la lista suministrada y ejecuta el bloque suministrado una vez para cada elemento. Cualquier tipo de lista puede ser usada para un ciclo for
. Por ejemplo:
for x in range(4): # por defecto range comienza con 0
print(x)
0 1 2 3
Nota: range(4)
no incluye el 4 !
for x in range(-3,3):
print(x)
-3 -2 -1 0 1 2
for palabra in ["computación", "científica", "con", "Python"]:
print(palabra)
computación científica con Python
Para iterar sobre pares clave-valor en un diccionario:
for clave, valor in parametros.items():
print(clave + " = " + str(valor))
parametro1 = A parametro3 = 3.0 parametro2 = B parametro4 = D
Algunas veces es útil tener acceso a los índices de los valores mientras se itera sobre una lista. Podemos usar la función enumerate
para esto:
for idx, x in enumerate(range(-3,3)):
print(idx, x)
(0, -3) (1, -2) (2, -1) (3, 0) (4, 1) (5, 2)
** Listas: Creando listas usando ciclos for
**:
Una forma conveniente y compacta de inicializar listas:
l1 = [x**2 for x in range(0,5)]
print(l1)
[0, 1, 4, 9, 16]
Ciclos while
:
i = 0
while i < 5:
print(i)
i = i + 1
print("listo")
0 1 2 3 4 listo
Note que el comandoprint("listo")
no es parte del cuerpo del ciclo while
, debido a su indentación.
En Python una función es definida usando la palabra clave def
, seguida de un nombre para la función, una variable entre paréntesis ()
, y el símbolo de dos puntos :
. El siguiente código, con un nivel adicional de indentación, is el cuerpo de la función.
def func0():
print("test")
func0()
test
En forma opcional, pero muy recomendada, podemos definir un "docstring", que es una descripción del propósito y comportamiento de la función. El docstring debería ser incluido directamente después de la definición de la función, antes del código en el cuerpo de la función.
def func1(s):
"""
Imprime la cadena 's' y dice cuántos caracteres tiene
"""
print(s + " tiene " + str(len(s)) + " caracteres")
help(func1)
Help on function func1 in module __main__: func1(s) Imprime la cadena 's' y dice cuántos caracteres tiene
func1("test")
test tiene 4 caracteres
Funciones que retornan un valor usan la palabra clave return
:
def cuadrado(x):
"""
Calcula el cuadrado de x.
"""
return x**2
cuadrado(4)
16
Podemos retornar múltiples valores desde una función usando las tuplas (ver más arriba):
def potencias(x):
dir """
Calcula algunas potencias de x.
"""
return x**2, x**3, x**4
potencias(3)
(9, 27, 81)
x2, x3, x4 = potencias(3)
print(x3)
27
En la definición de una función, podemos asignar valores por defecto a los argumentos de la función:
def mifunc(x, p=2, debug=False):
if debug:
print("evaluando mifunc para x = " + str(x) + " usando el exponente p = " + str(p))
return x**p
Si no suministramos un valor para el argumento debug
al llamar a la función mifunc
se considera el valor definido por defecto:
mifunc(5)
25
mifunc(5, debug=True)
evaluando mifunc para x = 5 usando el exponente p = 2
25
Si listamos explícitamente el nombre de los argumentos al llamar una función, ellos no necesitan estar en el mismo orden usando en la definición de la función. Esto es llamado argumentos de palabra clave (keyword), y son a menudo muy útiles en funciones que requieren muchos argumentos opcionales.
mifunc(p=3, debug=True, x=7)
evaluando mifunc para x = 7 usando el exponente p = 3
343
En Python podemos también crear funciones sin nombre, usando la palabra clave lambda
:
f1 = lambda x: x**2
# es equivalente a
def f2(x):
return x**2
f1(2), f2(2)
(4, 4)
Esta técnica es útil, por ejemplo, cuando queremos pasar una función simple como argumento de otra función, como en este caso:
# map es una función predefinida en Python
map(lambda x: x**2, range(-3,4))
[9, 4, 1, 0, 1, 4, 9]
# in Python 3 podemos usar `list(...)` para convertir la iteración a una lista explícita
list(map(lambda x: x**2, range(-3,4)))
[9, 4, 1, 0, 1, 4, 9]
Las clases son una característica clave de la programación orientada al objeto. Una clase es una estructura para representar un objeto y las operaciones que pueden ser realizadas sobre el objeto.
En Python una clase puede contener atributos (variables) y métodos (funciones).
En Python una clase es definida casi como una función, pero usando la palabra clave class
, y la definición de la clase usualmente contiene algunas definiciones de métodos (una función en una clase).
Cada método de una clase debería tener un argumento self
como su primer argumento. Este objeto es una autoreferencia.
Algunos nombres de métodos de clases tienen un significado especial, por ejemplo:
__init__
: El nombre del método que es invocado cuando el objeto es creado por primera vez.
__str__
: Un método que es invocado cuando se necesita una simple representación de cadena de la clase, como por ejemplo cuando se imprime.
Existen muchas más, ver http://docs.python.org/2/reference/datamodel.html#special-method-names
class Punto:
"""
Clase simple para representar un punto en un sistema de coordenadas cartesiano.
"""
def __init__(self, x, y):
"""
Crea un nuevo punto en x, y.
"""
self.x = x
self.y = y
def traslada(self, dx, dy):
"""
Traslada el punto en dx y dy en las direcciones x e y respectivamente.
"""
self.x += dx
self.y += dy
def __str__(self):
return("Punto en [%f, %f]" % (self.x, self.y))
Para crear una nuva instancia de una clase:
p1 = Punto(0, 0) # eso invoca el método __init__ en la cláse Punto
print(p1) # esto invoca el método __str__
Punto en [0.000000, 0.000000]
Para invocar un método en la instancia de clase p
:
p2 = Punto(1, 1)
p1.traslada(0.25, 1.5)
print(p1)
print(p2)
Punto en [0.250000, 1.500000] Punto en [1.000000, 1.000000]
Note que llamar a métodos de clases puede modificar el estado de esa instancia de clase particular, pero no afecta otras instancias de la clase o alguna otra variable global.
Esto es una de las cosas buenas de un diseño orientado al objeto: código como las funciones y variables relacionadas son agrupadas en entidades separadas e independientes.
La mayoría de la funcionalidad en Python es provista por módulos. La Librería Estándar de Python es una gran colección de módulos que proveen implementaciones multiplataforma de recursos tales como el acceso al sistema operativo, entrada/salido de archivos (file I/O), manejo de cadenas, comunicación en redes, y mucho más.
Para usar un módulo en un programa Python éste debe primero ser importado. Un módulo puede ser importado usando el comando import
. Por ejemplo, para importar el módulo math
, que contiene muchas funciones matemáticas estándar, podemos usar:
import math
Esto incluye el módulo completo y lo deja disponible para su uso en el programa. Por ejemplo, podemos escribir:
import math
x = math.cos(2 * math.pi)
print(x)
1.0
Alternativamente, podemos elegir importar todos los símbolos (funciones y variables) en un módulo al espacio de nombres (namespace) actual (de modo que no necesitemos usar el prefijo "math.
" cada vez que usemos algo del módulo math
:
from math import *
x = cos(2 * pi)
print(x)
1.0
Esta forma de proceder puede ser muy conveniente, pero en programas largos que incluyen muchos módulos es a menudo una buena idea mantener los símbolos de cada módulo en sus propios espacios de nombres, usando import math
. Esto elimina potenciales confusiones con eventuales colisiones de nombres.
Como una tercera alternativa, podemos importar sólo algunos símbolos seleccionados desde un módulo listando explícitamente aquellos símbolos que deseamos importar, en lugar de usar el carácter comodín *
:
from math import cos, pi
x = cos(2 * pi)
print(x)
1.0
Luego que se ha cargado un módulo, podemos listar los símbolos que éste provee usando la función dir
:
import math
dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
Usando la función help
podemos obtener una descripción de cada función (casi... no todas las funciones tienen docstrings, como se les llama técnicamente. Sin embargo, la mayoría de las funciones están documentadas de esta forma).
help(math.log)
Help on built-in function log in module math: log(...) log(x[, base]) Return the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x.
log(10) # calcula el logaritmo de 10 en base e
2.302585092994046
log(10, 2) # calcula el logaritmo de 10 en base 2
3.3219280948873626
También podemos usar la función help
directamente sobre los módulos:
help(math)
Algunos módulos muy útiles de la librería estándar de Python son os
(interfaz con el sistema operativo), sys
(Parámetros y funciones específicas del sistema), math
(funciones matem'aticas), shutil
(operaciones con archivos), subprocess
, multiprocessing
, threading
.
Una lista completa de los módulos estándar para Python 2 y Python 3 está disponible (en inglés) en http://docs.python.org/2/library/ y http://docs.python.org/3/library/, respectivamente. Una versión en español está disponible en http://pyspanishdoc.sourceforge.net/lib/lib.html.
Uno de los conceptos más importantes en programación es el de reusar código para evitar repeticiones.
La idea es escribir funciones y clases con un propósito y extensión bien definidos, y reusarlas en lugar de repetir código similar en diferentes partes del programa (programación modular). Usualmente el resultado es que se mejora ostensiblemente la facilidad de lectura y de mantención de un programa. En la práctica, esto significa que nuestro programa tendrá menos errores, y serán más fáciles de extender y corregir.
Python permite programación modular en diferentes niveles. Las funciones y las clases son ejemplos de herramientas para programación modular de bajo nivel. Los módulos Python son construcciones de programación modular de más alto nivel, donde podemos colectar variables relacionadas, funciones y clases. Un módulo Python es definido en un archivo Python (con extensión .py
), y puede ser accequible a otros módulos Python y a programas usando el comendo import
.
Considere el siguiente ejemplo: el archivo mimodulo.py
contiene una implementación simple de una variable, una función y una clase:
%more mimodulo.py
Podemos importar el módulo mimodulo
a un programa Python usando import
:
import mimodulo
Use help(module)
para obtener un resumen de lo que suministra el módulo:
help(mimodulo)
Help on module mimodulo: NAME mimodulo FILE /home/gr/Dropbox/Git/clases-python-cientifico/mimodulo.py DESCRIPTION Ejemplo de un módulo Python. Contiene una variable llamada mi_variable, una función llamada mi_function, y una clase llamada MiClase. CLASSES MiClase class MiClase | Clase ejemplo. | | Methods defined here: | | __init__(self) | | get_variable(self) | | set_variable(self, nuevo_valor) | Asigna self.variable a un nuevo valor FUNCTIONS mi_function() Función ejemplo DATA mi_variable = 0
mimodulo.mi_variable
0
mimodulo.mi_function()
0
mi_clase = mimodulo.MiClase()
mi_clase.set_variable(10)
mi_clase.get_variable()
10
Si hacemos cambios en el código de mimodulo.py
, necesitamos recargaro usando reload
:
reload(mimodulo) # sólo funciona en Python 2
<module 'mimodulo' from 'mimodulo.pyc'>
En Python los errores son manejados con una construcción especial de lenguaje llamada "Exceptions" (excepciones). Cuando ocurre un error, una excepción puede ser hecha, que interrumpe el flujo normal del programa y retorna a algún otro lugar del código donde se definan los comandos try-except más cercanos.
Para generar una excepción podemos usar el comando raise
, que toma un argumento que debe ser una instancia de la clase BaseExpection
o una clase derivada de ella.
raise Exception("descripción del error")
--------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-126-ae92a99eabb1> in <module>() ----> 1 raise Exception("descripción del error") Exception: descripción del error
Un úso típico de las excepciones es para abortar funciones cuando ocurre algún error, por ejemplo:
def mi_funcion(argumentos):
if not verify(argumentos):
raise Expection("Argumentos invalidos")
# el resto del código sigue aquí
Para capturar los errores que son generados por funciones y métodos de clases, o por el mismo intérprete Python, use los comandos try
y except
:
try:
# aquí va el código normal
except:
# el código para manejar el error va aquí
# Este código no se ejecuta a menos que
# el código de arriba genere un error
Por ejemplo:
try:
print("test")
# genera un error: ya que la variable test no está definida
print(test)
except:
print("Encontré una excepción")
test Encontré una excepción
Para obtener información sobre un error, podemos accesar la instancia de clase Exception
que describe la excepción usando por ejemplo:
except Exception as e:
try:
print("test")
# genera un error: ya que la variable test no está definida
print(test)
except Exception as e:
print("Encontré una excepción:" + str(e))
test Encontré una excepción:name 'test' is not defined
import sys
import IPython
print("Este notebook fue evaluado con: Python %s y IPython %s." % (sys.version, IPython.__version__))
Este notebook fue evaluado con: Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] y IPython 2.1.0.