Documente Academic
Documente Profesional
Documente Cultură
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
El lenguaje Python
Sobre Python
Python es un lenguaje de programacin de alto nivel de propsito general. Su filosofa de diseo hace incapi en un programador productivo y un cdigo fcil de leer. Tiene una sintaxis central minimalista con unos pocos comandos bsicos y semntica simple, pero tambin tiene una amplia y completa librera estndar, que incluye un API para trabajar con las funciones subyacentes de los sistemas operativos (OS). El cdigo Python, an cuando es minimalista, define objetos incorporados como listas enlazadas (list), tuplas (tuple), tablas hash (dict), y enteros arbitrariamente largos (long). Python soporta mltiples paradigmas de programacin, incluyendo programacin orientada a objetos (class), imperativa (def), y funcional (lambda). Python tiene un sistema de tipo dinmico y un manejo automtico 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 organizacin sin fines de lucro, Fundacin de Software Python. Hay muchos intrpretes y compiladores que implementan el lenguaje Python, incluyendo uno en Java (Jython) pero, en ste breve anlisis, nos referiremos a la implementacin en C creada por Guido. Usted puede encontrar muchos tutoriales, la documentacin oficial y referencias a libreras 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 captulo 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 intrprete de Python insertado en la distribucin 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 ms 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 versin superior 2.X) ya instalada, usted tendr que descargarlo e instalarlo antes de iniciar web2py. La opcin de lnea de comando -S welcome instruye a web2py a iniciar el terminal interactivo como si los comandos fueran ejecutados en un controlador para la aplicacin welcome, la aplicacin de andamiaje de web2py. ste expone casi todas las clases, objetos y funciones de web2py. sta es la nica diferencia entre la lnea de comandos interactiva de web2py y la lnea de comandos normal de Python. La interfaz de administracin tambin provee un terminal web para cada aplicacin. Usted puede acceder al de la aplicacin welcome desde: http://127.0.0.1:8000/admin/shell/index/welcome Usted puede probar todos los ejemplos en este captulo usando el terminal normal o el que est basado en web.
help, dir
El lenguaje Python provee dos comandos para obtener documentacin 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, obtendramos una descripcin acerca de la clase int y todos sus mtodos. 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 dinmicamente 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 dinmicamente 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
1 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
3 4 5 6 7 8 9
<type 'int'> >>> a = 3.14 >>> print type(a) <type 'float'> >>> a = 'hello python' >>> print type(a) <type 'str'>
Python tambin 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 mltiples lneas. 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 codificacin, como por ejemplo:
1 2 3 4 5 6
La ltima notacin es ms explcita y menos propensa a errores, y es preferida. Muchos objetos Python, por ejemplo nmeros, 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
Para clases definidas por el usuario, str y repr pueden ser definidos/redefinidos usando los operadores especiales __str__ y __repr__. stos se describen brevemente ms adelante; para ms informacin, revise la documentacin oficial de Python [39]. repr siempre tiene un valor por defecto. Otra caracterstica importante de una cadena Python es que, como las listas, es un objeto iterable.
1 2 3 4 5 6 7
list
Los principales mtodos 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
1 2 3 4 5 6
y concatenadas:
1 2 3 4
1 2 3 4 5 6
Los elementos de una lista no tienen que ser del mismo tipo; pueden ser cualquier tipo de objeto Python.
tupla
2 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
Una tupla es como una lista, pero su tamao 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 parntesis.
>>> a = (1, 2, 3)
1 2 3 4
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 slo elemento debe incluir una coma al final, como se muestra a continuacin:
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
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 mtodo __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 alfanumricos, un diccionario puede tambin ser declarado con la sintaxis alternativa:
1 2 3 4 5
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 mtodo 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.
3 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
1 2
Acerca de la Indentacin
Python usa indentacin para delimitar los bloques de cdigo. Un bloque comienza con una lnea que termina en dos puntos, y continua por todas las lneas que tengan una indentacin similar o superior en la siguiente lnea. Por ejemplo:
1 2 3 4 5 6 7 8
Es comn usar cuatro espacios para cada nivel de indentacin. Es una buena poltica no mezclar tabuladores con espacios, ya que pueden resultar en una confusin (invisible).
for...in
En Python, usted puede hacer un bucle sobre un objeto iterable:
1 2 3 4 5 6 7
Un atajo comn es xrange, el cual genera un rango iterable sin guardar la lista de elementos entera.
1 2 3 4 5 6
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
Tambin 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 ms pequeo 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
Tambin puede saltar a la siguiente iteracin de bucle sin ejecutar todo el bloque de cdigo con continue:
1 2 3 4 5 6 7
while
El bucle while en Python trabajo en su mayora como lo hace en los otros lenguajes de programacin, haciendo un bucle un nmero infinito de veces y verificando una condicin antes de cada iteracin. Si la condicin es falsa False, el bucle termina.
1 2 3 4 5
4 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
def...return
He aqu una tpica funcin Python:
1 2 3 4
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 mltiples 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 explcitamente 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
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 funcin 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
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 >>> >>> >>> >>> >>> >>> zero one other
elif significa else if. Tanto la clusula elif como la clusula else son opcionales. Puede haber ms de una declaracin elif pero slo una declaracin 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:
>>> try:
5 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
2 3 4 5 6 7 8 9 10
>>> 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 clusulas 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 descripcin detallada de cada una de ellas, revise la documentacin oficial de Python. web2py expone slo una nueva excepcin, llamada HTTP. Cuando es levantada, provoca que el programa devuelva una pgina de error HTTP (para ms sobre sto, revise el Captulo 4). Cualquier objeto puede ser levantado como una excepcin, pero es una prctica levantar objetos que extienden una de las clases de excepcin incluidas.
class
Debido a que Python es escrito de manera dinmica, las clases y objetos Python pueden parecer extraos. 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 estn 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 estticos en C++/Java). He aqu un ejemplo:
1 2 3 4 5
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 definicin de la clase indica que nuestra clase extiende la clase incluida object. sto no es requerido, pero es una buena prctica hacerlo. He aqu una clase ms 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 mtodos. Algunos mtodos tienen nombres reservados especiales. Por ejemplo, __init__ es el contructor. Todas las variables son variables locales del mtodo excepto las variables declaradas afuera de los mtodos. Por ejemplo, z es una variables de clase, equivalente a la variable de miembro esttica 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 conviccin, el nombre local usado dentro del mtodo para
6 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
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 mtodo dentro de otra clase.
1 2 3 4 5 6 7 8 9 10 11
>>> >>> >>> >>> >>> >>> >>> 4 >>> >>> [3,
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] a[1] = 7 print b.a 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 aritmticos. Para el uso de estos operadores referimos al lector a libros ms 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
1 2 3 4 5
Alternativamente usted puede leer en modo binario con "rb", escribir en modo binario con "wb", y abrir el archivo en modo aadir "a", usando la notacin estndar C
El comando read toma un argumento opcional, que es el nmero de bytes. Usted tambin puede saltar a cualquier ubicacin dentro del archivo usando seek. Usted puede leer desde un archivo con read
1 2 3
>>> file.close()
aunque normalmente no es necesario, debido a que los archivos se cierran automticamente 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 aplicacin actual. Las rutas pueden concatenarse con el comando os.path.join discutido ms 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
Qu acaba de suceder? La funcin exec le dice al intrprete que haga una llamada a si mismo y ejecute el contenido de la cadena pasada como argumento. Tambin es posible ejecutar el contenido de una cadena dentro de un contexto definido por los smbolos dentro de un diccionario:
1 2 3 4
Aqu el intrprete, al ejecutar la cadena a, ve los smbolos 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 cdigo interno puede hacer; slo define el conjunto de variables visibles para el cdigo. Una funcin relacionada es eval, la cual trabaja en su mayora como exec excepto porque espera el argumento a evaluarse con un valor, y luego devuelve ese valor.
7 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
1 2 3 4
import
El verdadero poder de Python est en sus modulos de libreras. Ellos proveen un amplio y consistente conjunto de APIs a muchos sistemas de libreras (a menudo en una manera independiente del sistema operativo). Por ejemplo, si usted necesita usar un generador de nmeros aleatorios, usted puede hacer:
1 2 3
Esto imprime un entero aleatorio entre 0 y 9 (9 includo), 5 en el ejemplo. La funcin randint es definida en el mdulo random. Tambin es posible importar un objeto desde un mdulo al espacio de nombres actual:
1 2
1 2
1 2
En el resto del libro, usaremos principalmente objetos definidos en los mdulos os, sys, datetime, time y cPickle. Todos los objetos web2py son accesibles por medio de un mdulo llamado gluon, y ese es el tema de los ltimos captulos. Internamente, web2py usa muchos mdulos Python (por ejemplo thread), pero raramente necesitar accesar a ellos de manera directa. En las siguientes subsecciones consideraremos los mdulos que son ms tiles. os Este mdulo provee una interfaz al API del sistema operativo. Por ejemplo:
1 2 3
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 concatenacin de rutas de manera independiente al OS:
1 2 3 4
que es un diccionario de slo lectura. sys El mdulo sys contiene muchas variables y funciones, pero el que ms usamos es sys.path. Contiene una lista de rutas donde Python busca los mdulos. Cuando tratamos de importar un mdulo, Python lo busca en todas las carpetas listadas en sys.path. Si usted instala mdulos adicionales en alguna ubicacin y quiere que Python los encuentre, usted necesita agregar la ruta a esa ubicacin en sys.path.
1 2
Al estar web2py en funcionamiento, Python reside en memoria, y slo hay un sys.path, mientras que hay muchas tareas sirviendo las solicitudes HTTP. Para evitar prdidas de memoria, es mejor verificar si una ruta ya est presente antes de agregar:
1 2 3
datetime El uso del mdulo datetime es ilustrado de mejor manera con algunos ejemplos:
1 2 3 4
>>> import datetime >>> print datetime.datetime.today() 2008-07-04 14:03:90 >>> print datetime.date.today()
8 de 9
29/05/2012 13:26
http://www.latinuxpress.com/books/drafts/web2py/caps/cap2.html
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 oposicin al tiempo local. En este caso usted puede usar la siguiente funcin:
1 2 3
Los mdulos 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
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 mdulo time difiere de date y datetime porque representatime como segundos de una poca (empezando por 1970).
1 2 3
Revise la documentacin de Python para informacin sobre conversin de funciones entre tiempo en segundos y tiempo como datetime. cPickle ste es un mdulo muy poderoso. Provee funciones que puede serializar casi cualquier objeto Python, incluyendo objetos auto-referenciales. Por ejemplo, contruyamos un objeto extrao:
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
En este ejemplo, b es una representacin 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
9 de 9
29/05/2012 13:26