El lenguaje Python

Sobre Python

Python es un lenguaje de programación de alto nivel de propósito general. Su filosofía de diseño hace incapié en un programador productivo y un código fácil de leer. Tiene una sintaxis central minimalista con unos pocos comandos básicos y semántica simple, pero también tiene una amplia y completa librería estándar, que incluye un API para trabajar con las funciones subyacentes de los sistemas operativos (OS). El código Python, aún cuando es minimalista, define objetos incorporados como listas enlazadas (list), tuplas (tuple), tablas hash (dict), y enteros arbitrariamente largos (long).

Python soporta múltiples paradigmas de programación, incluyendo programación orientada a objetos (class), imperativa (def), y funcional (lambda). Python tiene un sistema de tipo dinámico y un manejo automático de memoria usando conteo referencial (similar a Perl, Ruby, y Scheme).

Python fué lanzado primero por Guido van Rossum en 1991. El lenguaje tiene un modelo de desarrollo abierto, basado en la comunidad manejado por la organización sin fines de lucro, Fundación de Software Python. Hay muchos intérpretes y compiladores que implementan el lenguaje Python, incluyendo uno en Java (Jython) pero, en éste breve análisis, nos referiremos a la implementación en C creada por Guido.

Usted puede encontrar muchos tutoriales, la documentación oficial y referencias a librerías del lenguaje en el sitio web oficial de Python [2].

Para referencias Python adicionales, le podemos recomendar los libros en la ref. [37] y la ref. [38].

Usted puede obviar este capítulo si ya esta familiarizado con el lenguaje Python.

Comenzando

Las distribuciones binarias de web2py para Microsoft Windows y Apple OS X vienen empacadas con el intérprete de Python insertado en la distribución misma.

Usted puede iniciarlo en Windows con el siguiente comando (escriba en el terminal DOS):

web2py.exe -S welcome

En Apple OS X, ingrese el siguiente comando escribiendo en una ventana de Terminal (asumiendo que usted está en la misma carpeta que web2py.app):

./web2py.app/Contents/MacOS/web2py -S welcome

En Linux o algun otro sistema Unix, lo más probable es que usted ya tenga Python instalado. De ser así, en un terminal escriba:

python web2py.py -S welcome

Si usted no tiene Python 2.5 (o alguna versión superior 2.X) ya instalada, usted tendrá que descargarlo e instalarlo antes de iniciar web2py.

La opción de línea de comando -S welcome instruye a web2py a iniciar el terminal interactivo como si los comandos fueran ejecutados en un controlador para la aplicación welcome, la aplicación de andamiaje de web2py. Éste expone casi todas las clases, objetos y funciones de web2py. Ésta es la única diferencia entre la línea de comandos interactiva de web2py y la línea de comandos normal de Python.

La interfaz de administración también provee un terminal web para cada aplicación. Usted puede acceder al de la aplicación “welcome” desde:

http://127.0.0.1:8000/admin/shell/index/welcome

Usted puede probar todos los ejemplos en este capítulo usando el terminal normal o el que está basado en web.

help, dir

El lenguaje Python provee dos comandos para obtener documentación acerca de objetos definidos en el ámbito actual, ambos incluidos desde el comienzo y definidos por el usuario.

Podemos pedir ayuda ‘help‘ acerca de un objeto, por ejemplo “1”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
>>> help(1)
Help on int object:

class int(object)
 |  int(x[, base]) -> integer
 |
 |  Convert a string or number to an integer, if possible.  A floating point
 |  argument will be truncated towards zero (this does not include a string
 |  representation of a floating point number!)  When converting a string, use
 |  the optional base.  It is an error to supply a base when converting a
 |  non-string. If the argument is outside the integer range a long object
 |  will be returned instead.
 |
 |  Methods defined here:
 |
 |  __abs__(...)
 |      x.__abs__() <==> abs(x)
...

y, debido a que “1” es un entero, obtendríamos una descripción acerca de la clase int y todos sus métodos. Aquí la salida ha sido recortada debido a que es muy larga y detallada.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
>>> dir(1)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__',
'__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__',
'__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__',
'__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__',
'__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__',
'__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__',
'__str__', '__sub__', '__truediv__', '__xor__']

Tipos

Python es un lenguaje dinámicamente escrito, lo que significa que las variables no tienen una forma escrita, y por lo tanto no tienen que ser declaradas. Los valores, por el otro lado, si tienen una forma escrita. Usted puede hacer una consulta de una variable por el tipo de valor que contiene:

Python es un lenguaje dinámicamente escrito, lo que significa que las variables no tienen una forma escrita, y por lo tanto no tienen que ser declaradas. Los valores, por el otro lado, si tienen una forma escrita. Usted puede hacer una consulta de una variable por el tipo de valor que contiene:

1
2
3
4
5
6
7
8
9
>>> a = 3
>>> print type(a)
<type 'int'>
>>> a = 3.14
>>> print type(a)
<type 'float'>
>>> a = 'hello python'
>>> print type(a)
<type 'str'>

Python también incluye, de manera nativa, estructura de datos como listas y diccionarios.

str

Python soporta el uso de dos tipos diferentes de cadenas: cadenas ASCII y cadenas Unicode. Las cadenas ASCII se delimitan por ‘...’, ”...” o por “””...”“”. Las comillas triples delimitan cadenas con múltiples líneas. Las cadenas Unicode comienzan con una u seguida de cadena contentiva de los caracteres Unicode. Una cadena Unicode puede ser convertida a una cadena ASCII eligiendo una codificación, como por ejemplo:

1
2
3
4
5
6
>>> print 'number is ' + str(3)
number is 3
>>> print 'number is %s' % (3)
number is 3
>>> print 'number is %(number)s' % dict(number=3)
number is 3

La última notación es más explícita y menos propensa a errores, y es preferida.

Muchos objetos Python, por ejemplo números, pueden ser serializados en cadenas usando str o repr. Estos comandos son muy similares pero producen una salida un poco diferente. Por ejemplo:

1
2
3
4
>>> for i in [3, 'hello']:
     print str(i), repr(i)
3 3
hello 'hello'

Para clases definidas por el usuario, str y repr pueden ser definidos/redefinidos usando los operadores especiales __str__ y __repr__. Éstos se describen brevemente más adelante; para más información, revise la documentación oficial de Python [39]. repr siempre tiene un valor por defecto.

Otra característica importante de una cadena Python es que, como las listas, es un objeto iterable.

1
2
3
4
5
6
7
>>> for i in 'hello':
     print i
h
e
l
l
o

list

Los principales métodos de una lista Python son agregar, insertar, y borrar:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> a = [1, 2, 3]
>>> print type(a)
<type 'list'>
>>> a.append(8)
>>> a.insert(2, 7)
>>> del a[0]
>>> print a
[2, 7, 3, 8]
>>> print len(a)
4

Las listas pueden dividirse:

1
2
3
4
5
6
>>> print a[:3]
[2, 7, 3]
>>> print a[1:]
[7, 3, 8]
>>> print a[-2:]
[3, 8]

y concatenadas:

1
2
3
4
>>> a = [2, 3]
>>> b = [5, 6]
>>> print a + b
[2, 3, 5, 6]

Una lista es iterable, usted puede hacer un bucle sobre ella:

1
2
3
4
5
6
>>> a = [1, 2, 3]
>>> for i in a:
     print i
1
2
3

Los elementos de una lista no tienen que ser del mismo tipo; pueden ser cualquier tipo de objeto Python.

tupla

Una tupla es como una lista, pero su tamaño y elementos son inmutables, mientras que en una lista si son mutables. Si un elemento de la tupla es un objeto, los atributos del objeto son mutables. Una tupla se delimita por paréntesis.

1
>>> a = (1, 2, 3)

Así que mientras ésto funciona para una lista:

1
2
3
4
>>> a = [1, 2, 3]
>>> a[1] = 5
>>> print a
[1, 5, 3]

la asignación del elemento no funciona para una tupla:

1
2
3
4
5
6
7
>>> a = (1, 2, 3)
>>> print a[1]
2
>>> a[1] = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Una tupla, como una lista, es un objeto iterable. Note que una tupla que consiste de un sólo elemento debe incluir una coma al final, como se muestra a continuación:

1
2
3
4
5
6
>>> a = (1)
>>> print type(a)
<type 'int'>
>>> a = (1,)
>>> print type(a)
<type 'tuple'>

Las tuplas son muy útiles para empaquetamiento eficiente de los objetos debido a su inmutabilidad, y los corchetes son casi siempre opcionales:

1
2
3
4
5
6
>>> a = 2, 3, 'hello'
>>> x, y, z = a
>>> print x
2
>>> print z
hello

dict

Un dict-cionario Python es una tabla hash que mapea un objeto clave a un objeto de valor. Por ejemplo:

1
2
3
4
5
6
7
8
9
>>> a = {'k':'v', 'k2':3}
>>> a['k']
v
>>> a['k2']
3
>>> a.has_key('k')
True
>>> a.has_key('v')
:False

Las claves son de cualquier tipo hash (entero int, cadena string, o cualquier objeto cuya clase implemente el método __hash__). Los valores pueden ser de cualquier tipo. Claves diferentes y valores en el mismo diccionario no tienen que ser del mismo tipo. Si las claves son caracteres alfanuméricos, un diccionario puede también ser declarado con la sintaxis alternativa:

1
2
3
4
5
>>> a = dict(k='v', h2=3)
>>> a['k']
v
>>> print a
{'k':'v', 'h2':3}

Algunos métodos útiles son has_key, keys, values e items:

1
2
3
4
5
6
7
>>> a = dict(k='v', k2='3)>>> 
print a.keys()
['k', 'k2']
>>> print a.values()
['v', 3]
>>> print a.items()
[('k', 'v'), ('k2', 3)]

El método items produce una lista de tuplas, en la que cada una contiene una clave y su valor asociado.

Elementos Diccionario y elementos lista pueden ser borrados con el comando del:

1
2
3
4
5
6
7
8
>>> a = [1, 2, 3]
>>> del a[1]
>>> print a
[1, 3]
>>> a = dict(k='v', h2=3)
>>> del a['h2']
>>> print a
{'k':'v'}

Internamente Python usa el operador hash para convertir objetos en enteros, y usa ese entero para determinar donde guardar el valor.

1
2
>>> hash("hello world")
-1500746465

Acerca de la Indentación

Python usa indentación para delimitar los bloques de código. Un bloque comienza con una línea que termina en dos puntos, y continua por todas las líneas que tengan una indentación similar o superior en la siguiente línea. Por ejemplo:

1
2
3
4
5
6
7
8
>>> i = 0
>>> while i < 3:
>>>    print i
>>>    i = i + 1
>>>
0
1
2

Es común usar cuatro espacios para cada nivel de indentación. Es una buena política no mezclar tabuladores con espacios, ya que pueden resultar en una confusión (invisible).

for...in

En Python, usted puede hacer un bucle sobre un objeto iterable:

1
2
3
4
5
6
7
>>> a = [0, 1, 'hello', 'python']
>>> for i in a:
     print i
0
1
hello
python

Un atajo común es xrange, el cual genera un rango iterable sin guardar la lista de elementos entera.

1
2
3
4
5
6
>>> for i in xrange(0, 4):
     print i
0
1
2
3

Ésto es equivalente a la sintaxis C/C++/C#/Java:

for(int i=0; i<4; i=i+1) { print(i); }

Otro útil comando es enumerate, el cual cuenta mientras hace el bucle:

1
2
3
4
5
6
7
>>> a = [0, 1, 'hello', 'python']
>>> for i, j in enumerate(a):
     print i, j
0 0
1 1
2 hello
3 python

También hay una palabra clave range(a, b, c) que devuelve una lista de enteros comenzando por el valor a, incrementando por c, y termina con el último valor más pequeño que b, a es por defecto 0 y c es por defecto 1. xrange es similar pero en realidad no genera una lista, solo un iterador sobre la lista; por lo que es mejor para los bucles.

Usted puede salirse de un bucle usando break:

1
2
3
4
>>> for i in [1, 2, 3]:
      print i
      break
1

También puede saltar a la siguiente iteración de bucle sin ejecutar todo el bloque de código con continue:

1
2
3
4
5
6
7
>>> for i in [1, 2, 3]:
      print i
      continue
      print 'test'
1
2
3

while

El bucle while en Python trabajo en su mayoría como lo hace en los otros lenguajes de programación, haciendo un bucle un número infinito de veces y verificando una condición antes de cada iteración. Si la condición es falsa False, el bucle termina.

1
2
3
4
5
>>> i = 0
>>> while i < 10:
     i = i + 1
>>> print i
10

No hay una construcción loop...until (bucle hasta que) en Python.

def...return

He aquí una típica función Python:

1
2
3
4
>>> def f(a, b=2):
     return a + b
>>> print f(4)
6

No hay necesidad (ni manera) de especificar los tipos de los argumentos o el/los tipo(s) de retorno(s).

Los argumentos de las funciones pueden tener valores por defectos, y las funciones pueden devolver múltiples objetos:

1
2
3
4
5
6
7
>>> def f(a, b=2):
     return a + b, a - b
>>> x, y = f(5)
>>> print x
7
>>> print y
3

Los argumentos de las funciones pueden ser pasados explícitamente por nombre:

1
2
3
4
5
6
7
>>> def f(a, b=2):
     return a + b, a - b
>>> x, y = f(b=5, a=2)
>>> print x
7
>>> print y
-3

Las funciones pueden tomar un numero variable de argumentos:

1
2
3
4
5
6
7
>>> def f(*a, **b):
     return a, b
>>> x, y = f(3, 'hello', c=4, test='world')
>>> print x
(3, 'hello')
>>> print y
{'c':4, 'test':'world'}

Aqui los argumentos no pasados por nombre (3, ‘hello’) son almacenados en una lista a, y los argumentos pasados por nombre (c y test) son almacenados en el diccionario b.

En el caso opuesto, una lista o tupla puede ser pasada a una función que requiere argumentos posicionales individuales desempacandolos:

1
2
3
4
5
>>> def f(a, b):
     return a + b
>>> c = (1, 2)
>>> print f(*c)
3

y un diccionario puede ser desempacado para entregar argumentos de palabras claves:

1
2
3
4
5
>>> def f(a, b):
     return a + b
>>> c = {'a':1, 'b':2}
>>> print f(**c)
3

if...elif...else

El uso de condicionales en Python es intuitivo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> for i in range(3):
>>>     if i == 0:
>>>         print 'zero'
>>>     elif i == 1:
>>>         print 'one'
>>>     else:
>>>         print 'other'
zero
one
other

“elif” significa “else if”. Tanto la cláusula elif como la cláusula else son opcionales. Puede haber más de una declaración elif pero sólo una declaración else. Condiciones complejas pueden ser creadas usando los operadores not, and y or.

1
2
3
>>> for i in range(3):
>>>     if i == 0 or (i == 1 and i + 1 == 2):
>>>         print '0 or 1'

try...except...else...finally

Python puede lanzar - perdon, levantar- excepciones:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> try:
>>>     a = 1 / 0
>>> except Exception, e
>>>     print 'oops: %s' % e
>>> else:
>>>     print 'no problem here'
>>> finally:
>>>     print 'done'
oops: integer division or modulo by zero
done

Las cláusulas else y finally son opcionales.

Aqui hay una lista de las excepciones + HTML incluidos en Python (definidos por web2py)

BaseException
+-- HTTP (defined by web2py)
+-- SystemExit
+-- KeyboardInterrupt
+-- Exception
     +-- GeneratorExit
     +-- StopIteration
     +-- StandardError
     |    +-- ArithmeticError
     |    |    +-- FloatingPointError
     |    |    +-- OverflowError
     |    |    +-- ZeroDivisionError
     |    +-- AssertionError
     |    +-- AttributeError
     |    +-- EnvironmentError
     |    |    +-- IOError
     |    |    +-- OSError
     |    |         +-- WindowsError (Windows)
     |    |         +-- VMSError (VMS)
     |    +-- EOFError
     |    +-- ImportError
     |    +-- LookupError
     |    |    +-- IndexError
     |    |    +-- KeyError
     |    +-- MemoryError
     |    +-- NameError
     |    |    +-- UnboundLocalError
     |    +-- ReferenceError
     |    +-- RuntimeError
     |    |    +-- NotImplementedError
     |    +-- SyntaxError
     |    |    +-- IndentationError
     |    |         +-- TabError
     |    +-- SystemError
     |    +-- TypeError
     |    +-- ValueError
     |    |    +-- UnicodeError
     |    |         +-- UnicodeDecodeError
     |    |         +-- UnicodeEncodeError
     |    |         +-- UnicodeTranslateError
     +-- Warning
          +-- DeprecationWarning
          +-- PendingDeprecationWarning
          +-- RuntimeWarning
          +-- SyntaxWarning
          +-- UserWarning
          +-- FutureWarning
      +-- ImportWarning
      +-- UnicodeWarning

Para una descripción detallada de cada una de ellas, revise la documentación oficial de Python.

web2py expone sólo una nueva excepción, llamada HTTP. Cuando es levantada, provoca que el programa devuelva una página de error HTTP (para más sobre ésto, revise el Capítulo 4).

Cualquier objeto puede ser levantado como una excepción, pero es una práctica levantar objetos que extienden una de las clases de excepción incluidas.

class

Debido a que Python es escrito de manera dinámica, las clases y objetos Python pueden parecer extraños. De hecho, usted no necesita definir las variables de los miembros (atributos) al declarar una clase, y diferentes instancias de la misma clase pueden tener diferentes atributos. Los atributos están generalmente asociados con la instancia, no con la clase (excepto cuando son declarados como “atributos de clases”, que es lo mismo que “variables de miembros estáticos” en C++/Java).

He aquí un ejemplo:

1
2
3
4
5
>>> class MyClass(object): pass
>>> myinstance = MyClass()
>>> myinstance.myvariable = 3
>>> print myinstance.myvariable
3

Note que pass es un comando que no hace nada. En este caso es usado para definir una clase MyClass que no contiene nada. MyClass() llama al constructor de la clase (en este caso el constructor por defecto) y devuelve un objeto, una instancia de la clase. El objeto (object) en la definición de la clase indica que nuestra clase extiende la clase incluida object. Ésto no es requerido, pero es una buena práctica hacerlo.

He aquí una clase más compleja:

1
2
3
4
5
6
7
8
9
>>> class MyClass(object):
>>>    z = 2
>>>    def __init__(self, a, b):
>>>        self.x = a, self.y = b
>>>    def add(self):
>>>        return self.x + self.y + self.z
>>> myinstance = MyClass(3, 4)
>>> print myinstance.add()
9

Las funciones declaradas dentro de la clase son métodos. Algunos métodos tienen nombres reservados especiales. Por ejemplo, __init__ es el contructor. Todas las variables son variables locales del método excepto las variables declaradas afuera de los métodos. Por ejemplo, z es una variables de clase, equivalente a la variable de miembro estática C++ que contiene el mismo valor para todas las instancias de la clase.

Note que __init__ toma 3 argumentos y add toma uno, y sin embargo los llamamos con 2 o 0 argumentos respectivamente. El primer argumento representa, por convicción, el nombre local usado dentro del método para referirse al objeto actual. Aquí usamos self para referirnos a objeto actual, pero pudimos hacer usado cualquier otro nombre. self juega el mismo papel que *this en C++ o this en java, pero self no es una palabra clave reservada.

Ésta sintaxis es necesaria para evitar ambiguedad al declarar clases anidadas, tal como una clase que el local a un método dentro de otra clase.

Atributos, Métodos y Operadores especiales

Atributos, métodos y operadores de Clase que comienzan con un doble subrayado usualmente se desea que sean privados, aunque ésto es una convención que no se hace cumplir por el intérprete.

Alguno de ellos son palabras claves reservadas y tienen un significado especial.

Aquí, como un ejemplo, hay 3 de ellas:

  • __len__
  • __getitem__
  • __setitem__

Ellos pueden ser usadas, por ejemplo, para crear un objeto contenedor que actúa como una lista:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
>>> class MyList(object)
>>>     def __init__(self, *a): self.a = a
>>>     def __len__(self): return len(self.a)
>>>     def __getitem__(self, i): return self.a[i]
>>>     def __setitem__(self, i, j): self.a[i] = j
>>> b = MyList(3, 4, 5)
>>> print b[1]
4
>>> a[1] = 7
>>> print b.a
[3, 7, 5]

Otros operadores especiales incluyen __getattr__ y __setattr__, quienes definen los atributos get y set para la clase, y __sum__ y __sum__, quienes sobrecargan operadores aritméticos. Para el uso de estos operadores referimos al lector a libros más avanzados sobre este tema. Ya hemos mencionado los operadores especiales __str__ y __repr__.

Ingreso/Salida de archivos

En Python usted puede abrir y escribir en un archivo por:

1
2
>>> file = open('myfile.txt', 'w')
>>> file.write('hello world')

De manera similar, usted puede leer desde el archivo con:

1
2
3
4
5
>>> file = open('myfile.txt', 'r')
>>> print file.read()
hello world

     Alternativamente usted puede leer en modo binario con "rb", escribir en modo binario con "wb", y abrir el archivo en modo añadir "a", usando la notación estándar C.

El comando read toma un argumento opcional, que es el número de bytes. Usted también puede saltar a cualquier ubicación dentro del archivo usando seek.

Usted puede leer desde un archivo con read

1
2
3
>>> print file.seek(6)
>>> print file.read()
world

y puede cerrar el archivo con:

1
>>> file.close()

aunque normalmente no es necesario, debido a que los archivos se cierran automáticamente cuando la variable a la cual hacen referencia se encuentra fuera de alcance.

Cuando se usa web2py, usted no sabe donde está el directorio actual, porque depende de como esté configurado web2py. La variable request.folder contiene la ruta a la aplicación actual. Las rutas pueden concatenarse con el comando os.path.join discutido más abajo.

exec, eval

A diferencia de Java,m Python es un verdadero lenguaje interpretado. Esto significa que tiene la habilidad de ejecutar sentencias Python guardadas en cadenas. Por ejemplo:

1
2
3
>>> a = "print 'hello world'"
>>> exec(a)
'hello world'

¿Qué acaba de suceder? La función exec le dice al intérprete que haga una llamada a si mismo y ejecute el contenido de la cadena pasada como argumento. También es posible ejecutar el contenido de una cadena dentro de un contexto definido por los símbolos dentro de un diccionario:

1
2
3
4
>>> a = "print b"
>>> c = dict(b=3)
>>> exec(a, {}, c)
3

Aquí el intérprete, al ejecutar la cadena a, ve los símbolos definidos en c (b en el ejemplo), pero no ve a c o a. Esto es distinto que a un ambiente restringido, ya que since no limita lo que el código interno puede hacer; sólo define el conjunto de variables visibles para el código.

Una función relacionada es eval, la cual trabaja en su mayoría como exec excepto porque espera el argumento a evaluarse con un valor, y luego devuelve ese valor.

1
2
3
4
>>> a = "3*4"
>>> b = eval(a)
>>> print b
12

import

El verdadero poder de Python está en sus modulos de librerías. Ellos proveen un amplio y consistente conjunto de APIs a muchos sistemas de librerías (a menudo en una manera independiente del sistema operativo).

Por ejemplo, si usted necesita usar un generador de números aleatorios, usted puede hacer:

1
2
3
>>> import random
>>> print random.randint(0, 9)
5

Esto imprime un entero aleatorio entre 0 y 9 (9 incluído), 5 en el ejemplo. La función randint es definida en el módulo random. También es posible importar un objeto desde un módulo al espacio de nombres actual:

1
2
>>> from random import randint
>>> print randint(0, 9)

o importa todos los objetos de un módulo al espacio de nombres actual:

1
2
>>> from random import *
>>> print randint(0, 9)

o importa todo a un espacio de nombres nuevo:

1
2
>>> import random as myrand
>>> print myrand.randint(0, 9)

En el resto del libro, usaremos principalmente objetos definidos en los módulos os, sys, datetime, time y cPickle.

Todos los objetos web2py son accesibles por medio de un módulo llamado gluon, y ese es el tema de los últimos capítulos. Internamente, web2py usa muchos módulos Python (por ejemplo thread), pero raramente necesitará accesar a ellos de manera directa.

En las siguientes subsecciones consideraremos los módulos que son más útiles.

os

Este módulo provee una interfaz al API del sistema operativo. Por ejemplo:

1
2
3
>>> import os
>>> os.chdir('..')
>>> os.unlink('filename_to_be_deleted')

Alguna de las funciones os, tal como chdir, NO DEBEN SER USADAS en web2py porque no son seguras.

os.path.join es muy útil; permite la concatenación de rutas de manera independiente al OS:

1
2
3
4
>>> import os
>>> a = os.path.join('path', 'sub_path')
>>> print a
path/sub_path

Las variables de sistema se pueden acceder por medio de:

1
>>> print os.environ

que es un diccionario de sólo lectura.

sys

El módulo sys contiene muchas variables y funciones, pero el que más usamos es sys.path. Contiene una lista de rutas donde Python busca los módulos. Cuando tratamos de importar un módulo, Python lo busca en todas las carpetas listadas en sys.path. Si usted instala módulos adicionales en alguna ubicación y quiere que Python los encuentre, usted necesita agregar la ruta a esa ubicación en sys.path.

1
2
>>> import sys
>>> sys.path.append('path/to/my/modules')

Al estar web2py en funcionamiento, Python reside en memoria, y sólo hay un sys.path, mientras que hay muchas tareas sirviendo las solicitudes HTTP. Para evitar pérdidas de memoria, es mejor verificar si una ruta ya está presente antes de agregar:

1
2
3
>>> path = 'path/to/my/modules'
>>> if not path in sys.path:
        sys.path.append(path)

datetime

El uso del módulo datetime es ilustrado de mejor manera con algunos ejemplos:

1
2
3
4
5
>>> import datetime
>>> print datetime.datetime.today()
2008-07-04 14:03:90
>>> print datetime.date.today()
2008-07-04

En ocasiones usted puede necesitar colocar una etiqueta de tiempo a los datos basado en el tiempo UTC (tiempo universal coordinado), en oposición al tiempo local. En este caso usted puede usar la siguiente función:

1
2
3
>>> import datetime
>>> print datetime.datetime.utcnow()
2008-07-04 14:03:90

Los módulos datetime contienen varias clases: date, datetime, time y timedelta. La diferencia entre dos objetos date, o dos datetime, o dos time, es timedelta:

1
2
3
4
5
>>> a = datetime.datetime(2008, 1, 1, 20, 30)
>>> b = datetime.datetime(2008, 1, 2, 20, 30)
>>> c = b - a
>>> print c.days
1

En web2py, date y datetime son usados para almacenar los tipos SQL correspondientes al ser pasados o retornados desde la base de datos.

time

El módulo time difiere de date y datetime porque representatime como segundos de una época (empezando por 1970).

1
2
3
>>> import time
>>> t = time.time()
1215138737.571

Revise la documentación de Python para información sobre conversión de funciones entre tiempo en segundos y tiempo como datetime.

cPickle

Éste es un módulo muy poderoso. Provee funciones que puede serializar casi cualquier objeto Python, incluyendo objetos auto-referenciales. Por ejemplo, contruyamos un objeto extraño:

1
2
3
4
>>> class MyClass(object): pass
>>> myinstance = MyClass()
>>> myinstance.x = 'something'
>>> a = [1 ,2, {'hello':'world'}, [3, 4, [myinstance]]]

y ahora:

1
2
3
>>> import cPickle
>>> b = cPickle.dumps(a)
>>> c = cPickle.loads(b)

En este ejemplo, b es una representación cadena de a, y c es una copia de a generada al des-serializar b.

cPickle tambien puede serializar hacia y des-serializar desde un archivo:

1
2
>>> cPickle.dump(a, open('myfile.pickle', 'wb'))
>>> c = cPickle.load(open('myfile.pickle', 'rb'))

Contenidos

Tema anterior

Introducción

Próximo tema

Generalidades

Envíe sus comentarios o correcciones a comunidad@latinuxpress.com

Patrocinado por