+ All Categories
Home > Documents > Universidad Autónoma Metropolitana W&Y*

Universidad Autónoma Metropolitana W&Y*

Date post: 13-Feb-2022
Category:
Upload: others
View: 1 times
Download: 0 times
Share this document with a friend
111
Universidad Autónoma Metropolitana W&Y * División: Ciencias Básicas e Ingenieria Departamento: Ingenieria Eléctrica Licenciatura: Ingenieria Electrónica Area de Concentración: Computación Tesina para obtener el título de Ingeniero Electrónico. Título " El lenguaje de programación PYTHON" Autores: Miranda Mederos Arturo Arquimides 89225447 Miranda Mederos Lucio Espartaco 92321 745 Sello de la Coordinación Lugar : México D.F. Fecha : Noviembre del 2000 Trimestre Inicio : 98-1 Trimestre Fin ~98-P
Transcript

Universidad Autónoma Metropolitana W&Y*

División: Ciencias Básicas e Ingenieria

Departamento: Ingenieria Eléctrica

Licenciatura: Ingenieria Electrónica

Area de Concentración: Computación

Tesina para obtener el título de Ingeniero Electrónico.

Título

" El lenguaje de programación PYTHON"

Autores: Miranda Mederos Arturo Arquimides 89225447

Miranda Mederos Lucio Espartaco 92321 745

Sello de la Coordinación

Lugar : México D.F. Fecha : Noviembre del 2000 Trimestre Inicio : 98-1 Trimestre Fin ~ 9 8 - P

Contenido

1. Introducción 1.1. Primero es lo primero 1.2. Instalando Python 7,3. Modo lnteractivo

2. Instalación 2.1. El mejor caso: Una Instalación Trivial 2.2. El nuevo estándar: Distutils 2.3. La forma antigua: Ninguna norma 2.4. Distintas plataformas 2.5. Dividiendo el trabajo 2.6. Como trabaja el comando build 2.7. Como trabaja la instalación

3.1. Instalación Alterna: Unix (el esquema loca “the home schema”) 3.2. Instalación Alterna: Unix (el esquema prefijo “the prefix schema”) 3.3. Instalación Alterna: Windows 3.4. Instalación Alterna: MacOs

4. Instalación personalizada 5. Distutils: Configuración de Archivos

5.1. Localización y nombres de los archivos de configuración 5.2. Sintaxis de los archivos config

6.1. Llamar al intérprete

3. Instalación Alterna

6. Utilización del interprete de Python

6.1 .l. Traspaso de Argumentos 6.1.2. Modo interactivo

6.2. El intérprete y su entorno 6.2.1. Gestión de errores 6.2.2. Guiones ejecutables en Python 6.2.3. El fichero de arranque interactivo

7. Tipos de Datos 7.1. Números

7.1 . l . Enteros 7.1.2. Números Reales 7.1.3. Números Complejos 6 imaginarios 7.1.4. Valores Boléanos -Verdadero y Falso 7.1.5. Operaciones a nivel de bits sobre enteros

7.2.1. Métodos de las cadenas 7.2.2. Operaciones de formato de las cadenas 7.2.3. El tipo xrange (rango dinámico) 7.2.4. Tipos de secuencias mutables 7.2.5. Tipos de correspondencias

7.2. Secuenciales

7.3. Cadenas 7.4. Cadenas Unicode 7.5. Listas

7.6. Variables 7.7. Otros tipos Internos

7.7.1. Módulos 7.7.2. Clases e Instancias de las Clases 7.7.3. Funciones 7.7.4. Métodos

7.7.6. Objetos Tipo

7.7.8. El objeto elipsis

7.8. Atributos especiales

8.1. While 8.2. For 8.3. If

7.7.5. Objetos Código

7.7.7. El objeto Nulo

7.7.9. Objetos ficheros

8. Estructuras de Control de Flujo

9. Un primer Acercamiento 9.1. Imprimiendo líneas en pantalla

9.3. Hablando con los humanos (y otros inicios inteligentes) 9.2. Expresiones

9.4. Datos de Entrada 10. Definición de Funciones 1 1. Estructuras de Datos

11.1. Más sobre las listas 11 .I .l. Como usar las listas como pilas I 1 .I .2. Como usar las listas como colas 11 .I .3. Herramientas de programación funcional

11.2. La sentencia del 11.3. Tuplas y secuencias 1 I .4. Diccionarios 11 5 . Más sobre las condiciones 11.6. Comparación entre secuencias y otros

12.1. Más sobre los módulos

12.2. Módulos estándar 12.3. La función dk() 12.4. Paquetes

12. Módulos

12.1 .l. El camino de búsqueda de los módulos

12.4.1. Import * de un paquete 12.4.2. Referencias internas al paquete

13. Entrada y salida 13.1. Formato de salida mejorado 13.2. Lectura y escritura de ficheros

13.2.1. Métodos de los objetos fichero 13.2.2. El módulo picle

14. Clases 14.1. Unas palabras sobre la terminología

14.2. Ámbitos y espacios nominales en Python 14.3. Un primer vistazo a las clases

14.3.1. Sintaxis de definición de funciones 14.3.2. Objetos Clase 14.3.3. Objetos instancia 14.3.4. Objetos método

14.4. Cajón de sastre 14.5. Herencias

14.6. Variables privadas 14.7. Remates

14.5.1. Herencia múltiple

14.7.1. Las excepciones pueden ser clases 15. Excepciones Internas 16. Servicios de ejecución de Python

16.1. sys -- Parámetros y funciones específicas del sistema 16.2. gc -- lnterfaz recolectora de basura 16.3. ataexit -- Gestores de salida 16.4. types -- Nombre para todos los tipos built-in 16.5. UserDict - Empacador de clases para los objetos diccionario 16.6. UserList -- Empacador de clases para objetos Lista 16.7. UserList -- Empacador de clases para objetos String 16.8. operator -- Operaciones estándar con funciones

Apéndice A Bibliografía

1 . Introducción.

Python es un lenguaje de programación fácil de aprender y potente. Tiene eficaces estructuras de datos de alto nivel y una solución de programación orientada a objetos simple pero eficaz. La elegante sintaxis de Python, su gestión de tipos dinámica y su naturaleza interpretada hace de éI el lenguaje ideal para guiones (scripts) y desarrollo rápido de aplicaciones, en muchas áreas y en la mayoría de las plataformas. El intérprete de Python y la extensa biblioteca estándar están disponible libremente, en forma de fuentes o ejecutables, para las plataformas más importantes en la sede web de Python, http://www.PYthon.org, y se pueden distribuir libremente. La misma sede contiene también distribuciones y direcciones de muchos módulos, programas y herramientas Python de terceras partes, además de documentación adicional. Es fácil ampliar el intérprete Python con nuevas funciones y tipos de datos implementados en C y C++ (u otros lenguajes a los que se pueda acceder desde C). Python es también adecuado como lenguaje de extensión para aplicaciones adaptables al usuario.

Python resulta ser un buen lenguaje para aprender a programar, Su sintaxis es sencilla y tiene incorporadas características muy poderosas. Permite diversos estilos de programación, incluyendo tanto técnicas convencionales como las más modernas orientadas a objetos. Corre en diversas plataformas como Unices, Unix/Linux, MS Windows, Macintosh, OS/2, etc. Python incluye muchas características modernas de lenguaje de programación junto con muchos conjuntos de funciones estándar (packages). Python puede ser usado para CGI scripts, administración de sistemas, generación de código, interfaz gráfica, conversiones de formato de archivo, y muchas otras tareas computacionales, pero el más excitante uso de Python es por lo general la ingeniería de software y el desarrollo de productos.

La "biblioteca de Python" contiene varias clases diferentes de componentes. Contiene tipos de datos que se considerarían normalmente parte del "núcleo" del lenguaje, tales como números y listas. En estos tipos, el núcleo del lenguaje Python define la forma de las constantes literales e impone ciertas restricciones sobre la semántica, pero no define exhaustivamente la semántica (por otra parte, el núcleo del lenguaje sí define las propiedades sintácticas como la ortografía y prioridades de los operadores). La biblioteca también contiene funciones y excepciones internas, objetos que se pueden utilizar desde todo el código Python sin necesidad de una sentencia import. A veces, se definen en el núcleo, pero no son esenciales para el núcleo semántico y sólo se describen aquí. El grueso de la biblioteca, no obstante, consta de una colección de módulos. Hay muchos modos de diseccionar esta colección. Algunos módulos están escritos en C y son internos al intérprete, otros están en Python y se importan en forma de código fuente. Algunos módulos proporcionan interfaces específicas alternas a Python, como presentar una traza de la pila, otros proporcionan interfaces específicas de un sistema operativo, como acceso a hardware específico, otros proporcionan interfaces específicas de un dominio de aplicaciones, como la Web. Algunos módulos están disponibles en todas las versiones de Python de todos los sistemas operativos, otros sólo están disponibles si el sistema subyacente les da soporte o los necesitan.

Python es simple, pero es un lenguaje de programación real. Ofrece más apoyo e infraestructura para programas grandes que el intérprete de órdenes. Por otra parte, también ofrece mucha más comprobación de errores que C y, al ser un lenguaje de muy alto nlvd, tlene lncluldos tipos de datos de alto nivel, como matrices flexibles y diccionarios, que llevarían días de programación en C. Dados sus tipos de datos más

generales, se puede aplicar a un rango de problemas más amplio que Awk o incluso Per/, pero muchas cosas son, al menos, igual de fáciles en Python que en esos lenguajes. Python te permite dividir su programa en módulos reutilizables desde otros programas Python. Viene con una gran colección de módulos estándar que puedes utilizar como base de tus programas (o como ejemplos para empezar a aprender Python). También hay módulos incluidos que proporcionan E/S de ficheros, llamadas al sistema, sockets y hasta interfaces a IGU (interfaz gráfica con el usuario) como Tk. Python es un lenguaje interpretado, lo que ahorra un tiempo considerable en el desarrollo del programa, pues no es necesario compilar ni enlazar. El intérprete se puede utilizar de modo interactivo, lo que facilita experimentar con características del lenguaje, escribir programas desechables o probar funciones durante el desarrollo del programa de la base hacia arriba. También es una calculadora muy útil. Python permite escribir programas muy compactos y legibles. Los programas escritos en Python son típicamente mucho más cortos que sus equivalentes en C o C++, por varios motivos:

0 Los tipos de datos de alto nivel permiten expresar operaciones complejas en una

0 El agrupamiento de sentencias se realiza mediante sangrado (indentación) en sola sentencia.

lugar de begidend o llaves. No es necesario declarar los argumentos ni las variables.

1.1 Primero es lo primero.

La única forma de aprender a programar. Usted debe de leer código y escribir código. Usted debería escribir cada uno de los ejemplos que se muestran. Hacer cambios sobre los mismos para ver que sucede. Lo peor que puede pasar es que no funcione.

1.2. Instalando Python

Lo primero que se tiene que hacer es bajar los archivos apropiados desde http://www.python.orddowload. Vaya al link más nuevo y entonces obtenga el instalador de Windows si usted es usuario de Windows ó el rpm o fuentes si usted es usuario de Uníx.

El instalador de Windows puede ser bajado a archivo. El archivo puede ser ejecutado haciendo doble click en el icono que se bajo. Entonces se puede proceder a la instalación. Para obtener más detalles consulte éI capitulo 2.

1.3 Modo lnteractivo

Vaya al IDLE (GUI de Python). Usted podrá ver una ventana que tiene algún texto como este:

Python 2.0 (#4, Dec 12 2000, 19: 19:57) [GCC 2.95.2 20000220 (Debian GNU/Linux)] on linux2 Type "copyright", "credits" or "license" for more information. IDLE 0.6 -- press F1 for help >>>

El símbolo >>> es la forma en que Python nos indica que usted esth en modo interactivo. En el modo interactivo usted puede ejecutar cualquier comando y este es ejecutado inmediatamente. Por ejemplo si usted teclea 1 + 1 Python le responderá con 2 El modo interactivo le permite ver y validar que es lo que Python hará.

2. Instalación.

El primer paso para usar Python es encontrarlo. La forma tradicional para conseguir Python es por FTP. Los nombres de los sitios (sites) de Python pueden cambiar, pero el principal sitio Python en internet es ftp://ftp.pvthon.orq/pub/python/src.

2.1. El mejor Caso: Una Instalación Trivial

En el caso mejor, alguien habrá preparado una versión especial de la distribución del módulo que usted quiere instalar eso está específicamente el targeted en su plataforma y simplemente se instala como cualquier otro software en su plataforma. Por ejemplo, el diseñador del módulo podría hacer un instalador ejecutable disponible para los usuarios de Windows, una RPM el paquete para los usuarios de sistemas de Linux Rpm- basado (el Sombrero Rojo, SuSE, la Mandrágora, y muchos otros), un paquete de Debian para los usuarios de sistemas de Linux Debian-basado (Debian apropiado, Caldera, Corel, etc.)

En ese caso, usted transmitiría el instalador apropiado a su plataforma y haría la cosa obvia con éI: ejecútelo si es un instalador ejecutable, la rpm - lo instala si es una RPM, el etc. Usted no necesita ejecutar Pitón o una escritura del arreglo, usted no necesita compilar algo--usted no podría necesitar leer cualquier instrucción ni siquiera (aunque siempre es una idea buena hacer esto)

Claro, las cosas no siempre serán ese fácil. Usted podría estar interesado en una distribución del módulo que no tiene un instalador del fácil-a-uso para su plataforma. En ese caso, usted tendrá que empezar con la distribución de la fuente dejado por el author/maintainer del módulo. Instalando desde de la fuente de distribución no es demasiado duro, con tal de que los módulos se empaqueten de la manera normal. El volumen de este documento está sobre construir e instalar los módulos de las distribuciones de la fuente normales.

2.2. El nuevo estándar: Distutils

Si usted baja el módulo desde la fuente de distribución, usted puede decir bastante rápidamente si fue empaquetado y distribuyó de la manera normal, es decir usando el Distutils. Primero, se ofrecerán el nombre de la distribución y número de la versión de forma prominente en el nombre del archivo transmitido, por ejemplo foo-1.0.tar.gz o widget-0.9.7.zip. Próximo, el archivo desempaquetará en un directorio semejantemente- nombrado: foo-1 .O o widget-0.9.7. Adicionalmente, la distribución contendrá una escritura del arreglo setup.py, y un README.txt (o posiblemente README), el cual podría explicar que la construcción e instalación del módulo distribuido, es tan simple como ejecutar:

python setup.py install

Si todas estas cosas son verdad, entonces usted ya sabe cómo construir e instalar los módulos: ejecute el orden anteriormente. A menos que usted necesita instalar las cosas de una manera non-normal o personalizar el proceso de la figura, usted realmente no necesita este manual. O más bien, el orden anterior es todo Io que usted necesita saber de este manual.

2.3. La forma antigua: Ninguna norma.

Antes de los DISTUTILS, no había infraestructura para soportar la instalacidn de las tres partes de los módulos en una forma consistente y estandarizada. Por ello no es posible escribir un manual general para la instalación de los módulos de Python que no usen el Distutils; la única declaración general que se puede hacer es “Lea las propias instrucciones de la instalación del módulo”.

Sin embargo si dichas instrucciones existen por lo regular son inadecuadas y están dirigidas a experimentados desarrolladores de Python. Dichos usuarios ya están familiarizados con cómo la biblioteca de Python se pone en su plataforma, y conocen donde copiar varios archivos en el orden en que Python los encuentre.

2.4. Distintas plataformas.

Debería siempre ejecutar el comando de SETUP desde el directorio de distribución. ¡.e. el subdirectorio que se encuentra en el top-level que el módulo distribuido desempaco. Por ejemplo si ha descargado el archivo foo-?.O.tar.gz en un sistema Unix, la cosa más normal que se tiene que hacer es:

gunzip -c foo-I .O.tar.gz I tar xf - # unpacks into directory foo-I .O

python setup.py install cd foo-I .O

En Windows probablemente descargo el archivo foo-?.O.zip Si descargo el archivo al directorio C I T E “ , entonces debe desempacar en C:\T€MP\ foo-l.0.zip; para desempaca rl archivo puede utilizar dos herramientas, un comando de línea para desempacar el archivo (unzip ó pkunzip) ó manejador de archivo como el WinZip. Entonces, abra la ventana del prompt de comandos (“DOS box”), y corra

cd c:\Temp\foo-I .O Python setup.py install

En MacOS, usted tiene que hacer más esfuerzo para proporcionar los argumentos

Haga doble clic en el icono del script 0 Presione el boton para poner en línea de comando el editor de Unix. 0 Cuando la línea de comando esta activa digite la palabra install

del orden-línea a la escritura del arreglo:

2.5. Dividiendo el trabajo

Corriendo el instalador setup.py construye e instala todos los módulos en una corrida. SI prefiere personaliza el proceso de construcción, ó si piensa que está haciendo algo mal, puede utilizar el script del setup para hacer una cosa a la vez. Esto es particularmente de mucha ayuda cuando la instalación es hecha por diferentes usuarios. e.g. usted desea construir un módulo de distribución y entregar este a un sistema administrador para su instalación (o hacer esto por usted mismo con privilegios de un supero usuario).

Por ejemplo, usted puede construir todo en un paso, y entonces instalar todo en un segundo paso, invocando el script de setup dos veces:

python setup.py build python setup.py install

(Si usted hace esto, notara que al ejecutar el comando install, primero ejecutará el comando build, el cual en este caso rápidamente notará que no tiene nada que hacer, entonces todos los archivos que se encuentran en el directorio build han sido actualizado en su fecha)

2.6. Como trabaja el comando Build.

Como se especifico arriba, el comando build es el responsable de poner los archivos que van a ser instalados en el directorio build. Por default este directorio está, en el directorio raíz; si usted está excesivamente interesado en la velocidad, 6 si quiere mantener el directorio raíz puede cambiar el directorio build con la opción build-base. Por ejemplo

python setup.py build --build-base=/tmp/pybuild/foo-I .O

(o puede hacer esto permanentemente con una directiva en su sistema ó en el archivo de configuración Distutils). Normalmente esto no es necesario.

El layout por default para la construcción del directorio es:

--- build/ --- lib/ O

--- build/ --- lib.<plat>/ temp.<plat>/

Donde <plat> da una amplia descripción de la actual plataforma OS/Hardware y la versión de Python. La primera sentencia, solo con el directorio lib, es usada “solamente para el módulo de distribución” esto es, los módulos de distribución que incluyen solo los módulos de Python. Si un modulo de distribución contiene cualquier otra extensión ( módulos escritos en C/C++), entonces la segunda forma, con dos directorio <plat> es usado. En este caso el directorio Temp. <plat> mantiene temporalmente los archivos generados por los procesos de compilación y ligado que actualmente no han sido instalados. En ambos casos el directorio lib ó lib.plat contiene todos los módulos de Python (solo los modulo de Python y sus extensiones) que pueden ser instalados.

2.7. Como trabaja la instalación

Después de que el comando build fue ejecutado, el trabajo del comando install es relativamente simple, todo lo que tiene que hacer es todo lo que este bajo el directorio build/lib (o build/lib.plaf) a su directorio de instalación.

Si no elige un directorio de instalación ¡.e. si solo ejecuta el comando setup.py install, entonces el comando install instala los tres módulos de Python en un directorio estándar. Esta localización varia dependiendo de la plataforma sobre la cual se esté instalando Python y por como tu constructor instale el Python mismo. En Unix y MacOs depende donde haya sido instalado el módulo distribuido, si contiene extensiones ó es puro.

Notas

1. Muchas distribuciones de Linux incluyen Python como un estándar del sistema, así prefix y exec-prefix son por lo regular /usr en Linux. Si construye usted mismo Python sobre Linux, los los valores prefix y exec-prefix son lusrllocal.

2. El directorio de instalación por default en Windows fue C:\PROGRAM FILES\PYTHON bajo Python 1.6x, 1.5.2 y anteriores.

3. Una Instalación alterna

A menudo, es necesario o deseable instalar los módulos en otra directorio, en lugar del directorio que se genera por default cuando se hace la instalación de Python. Por ejemplo, en un sistema de Unix usted no podría tener el permiso para escribir hacia cualquier directorio. O usted podría desear probar un módulo antes de hacerlo su instalación local de Python; esto es especialmente verdad al actualizar la versión: Si usted quiere asegurarse que existan los scripts con los cuales trabaja la nueva versión antes de que se actualice la instalación.

Los comando install de Distutils esta diseñando para hacer la instalación alterna del módulo en un directorio alterno. La idea básica es que usted proporcione un directorio base para la instalación, y el comando install escoge un conjunto de directorios (llamado un esquema de instalación) bajo este directorio se instalaran los archivos. Los detalles difieren con el tipo de plataforma, así que identifique cual de las siguientes secciones aplica a su plataforma.

3.1. Instalación Alterna: Unix (el esquema local “the home schema”)

Bajo al ambiente Unix hay dos formas de realizar una instalación alterna. El prefijo “prefix schema” es similar a cómo la instalación alterna trabaja bajo Windows y MacOS, pero necesariamente no es la manera más útil de mantener una biblioteca personal en la instalación de Python. En esta documentación utilizaremos la palabra “home schema”.

La idea detrás de “home schema” es que usted construya y mantenga en un lugar seguro un grupo de módulos de Python, probablemente bajo el directorio raíz. Instalar un nuevo módulo de distribución es tan simple como escribir:

python setup.py install --home=<dir>

Donde se puede sustituir cualquier directorio por la opción - home. Si usted considera que es muy importante su tiempo puede teclear una simple tilde (); el comando install expandirá este hacia su directorio elegido:

python setup.py install --home=-

La opción home define el directorio base de instalados bajos las siguientes condiciones de instalación.

Tipo de Archivo

Solo del módulo distribuido Módulo distribuido y otros Scripts Datos

Directorio de Instalación

home/lib/python

home/lib/python hornelbin homekhare

instalación. Los archivos son

Override Option

--install-purelib

--install-platlib --install-scripts --install-data

3.2. Instalación Alterna: Unix (el esquema prefijo “the prefix schema”)

El “prefix schema” es usado cuando usted desea usar una instalación de Python utilizando la opción build/install, para instalar los módulos en el tercer módulo de los directorios de instalación. Esto suena muy inusual, esto es debido a que el “home schema” es primero. Sin embargo, hay al menos dos casos conocidos don el “prefix schema” es útil.

Considere que Linux pone Python en /us, en lugar de lo más tradicional /usr/local. Esto es completamente correcto, esto es por que en estos casos Python es parte de “el sistema”. Sin embargo si usted está instalando Python desde la fuente (CD-ROM), probablemente quiera hacer esto en /usr/local/lib/python l . X en lugar de /usr/lib/python 1 .X. Esto puede ser hecho con:

/usr/bin/python setup.py install --prefix=/usr/local

Otra posibilidad es un sistema de archivos en red (network filesystem) donde el nombre usado para escribir a un directorio remoto es diferente al nombre de donde se lee este: por ejemplo si el acceso al interprete de Python es con /usr/local/bin/python, debe buscar los módulos en /usr/local/lib/python 1.X, pero estos módulos deben ser instalados en, /mnt/@,server/export/lib/python 1 .X. Esto puede ser hecho con:

/usr/local/bin/python setup.py install --prefix=/mntl@server/export

En ambos casos -prefix, define la base de la instalación (directorios) y la opción -- exec -- prefix define la plataforma sobre la cual se va a instalar, la cual es utilizada para los archivos específicos de la plataforma (esto significa que el módulo distribuido no es puramente de Python, pero se puede a librerías C, ejecutables binarios, etc.) Si -exec- prefix no es proporcionado por defalut es -prefix. Los archivos son instalados como sigue:

Tipo de Archivo

Sólo el módulo distribuido

Directorio de Instalación Override Option

prefix/lib/pythonl .X/site-packages --install-purelib

Módulo distribuido y exec-prefix/lib/pythonl .X/site- otros packages

-install-platlib

Scripts Datos

prefix/bin prefidshare

--install-scripts --install-data

Aquí no es necesario que -prefix o -exec-prefix estén apuntando a directorios que ya existan, si no existen son creados al momento en que se haga la instlación.

A propósito, el motivo real del esquema de prefijo (“the prefix schema”) es, simplemente que el estándar de instalación en Unix usa el esquema de prefijo (“the prefix schema”), pero con -prefix y -exec-prefix suplidos por Python (como sys.prefix y

sys.exec-prefix). Por ello debería pensar en nunca utilizar el esquema de prefijo ("the prefix schema"). Pero cada vez que ejecute el comando setup.py sin ninguna otra opción, lo estará usando.

3.3. Instalación Alterna: Windows

Debido a que Windows no tiene un concepto de directorio de usuario, y debido a que la instalación estándar bajo Windows es más simple que la instalación sobre Unix, no tiene sentido tener por separado las opciones --prefix y -home, debido a que la opción -- prefix especifica el directorio base, e.g.

python setup.py install --prefix="\Temp\Python"

para instalar los módulos en el directorio \TEMP.

La instalación base está definida por las opciones - prefix; la opción --exec-prefix no es soportada en Windows. Los archivos son instalados como sigue:

Tipo de archivo

Solo el módulo distribuido

Directorio de Instalación

prefix

Override Option

Módulo distribuido y prefix otros

-install-purelib

,-install-platlib

Scripts Datos

prefix\Scripts --install-scripts prefix\Data --install-data

3.4 Instalación Alterna: MacOS

AI igual que Windows MacOs no tiene opciones para el directorio de usuario, la instalación de Python es muy sencilla. Pues eso, solo se necesita la opción -prefix. Esto define la instalación base, y los archivos son instalados como sigue:

Tipo de archivo

Solo el módulo distribuido

Directorio de Override Instalación Option

prefix:Lib:site-packages --install-purelib

-install-platlib

Scripts Datos

prefix:Scripts --install-scripts prefix:Data --install-data

4. Una instalación personalizada.

En ocasiones, los esquemas de instalación alternos descritos en la sección 3, no son lo que usted realmente desea hacer. Usted desearía cambiar uno o dos directorios mientras mantiene todo baja un mismo directorio base, o usted desearía redefinir completamente el esquema de instalación. En ambos casos, usted está creando un esquema de instalación personalizada.

Usted probablemente noto la columna de “Override Option” en las tablas que describen un esquema de instalación alterna. Dichas opciones son las que definen un esquema de instalación personalizado. Estas “Override Option” pueden ser definidas de una forma relativa, absoluta ó explicita en términos de uno de los directorios que se toman como base para la instalación. (Hay dos directorios base de Instalación y son normalmente los mismos - solo difieren cuando se usa el esquema prefijo (“prefix schema”) en Unix y solo definir las opciones -- prefix y --exec-prefix.

Por ejemplo, digamos que usted está instalando un módulo distribuido a su directorio origen (“home directory”) bajo Unix pero usted quiere que los script estén en /scripts en lugar de /bin. Como usted espera, usted puede sobrescribir los directorios con la opción -- install - script; en este caso tiene más sentido cambiar el path de instalación, el cual puede ser interpretado como alterno al directorio base de instalación (su directorio origen (“home directory”)en este caso)

python setup.py install --home=- --install-scripts=scripts

Otro ejemplo en Unix: Supongamos que su instalación de Python fue construida e instalada con el prefijo /usr/local/python, Los scripts se instalaran bajo el directorio /usr/local/python/bin. Si usted quiere cambiar el directorio de instalación, usted debe suplir todo este directorio por las opciones -- install - script:

python setup.py install --install-purelib=Site --install-platlib=Site

Estos directorios específicos de instalación están relacionados a la opción -prefix. Por supuesto usted se ha asegurado que estos directorios existan en el path del módulo de búsqueda de Python, e.g. poniendo un path. En el archivo prefix. (** debería tener una sección donde se describan los archivos pth y las referencias cruzadas**)

Si usted quiere definir un nuevo esquema de instalación, usted tiene que proporcionar todos las opciones para los directorios de instalación. La forma más recomendable para hacer esto es proporcionar paths relativos; por ejemplo, si usted quiere mantener todos los módulos relacionados bajo Python en su directorio origen “home directory”, y usted quiere un directorio separado para cada una de las plataformas que usted usa desde su directorio origen “home directory” usted debe definir el siguiente esquema de instalación:

python setup.py install --home=- \ --install-purelib=python/lib \ --install-platlib=python/lib.$PLAT \ --install-scripts=python/scripts --install-data=python/data

o su equivalente,

python setup.py install --home=-/python \ --install-purelib=lib \

--install-scripts=scripts --install-data=data

--install-platlib='lib.$PLAT' \

$PLAT no es (necesario) en un ambiente variable, será expandido por el Distituls como aparece en las opciones de la línea de comando.

Obviamente especificar el esquema de instalación cada vez usted instale un nuevo módulo distribuido puede ser muy tedioso. Por ello usted puede poner las siguientes opciones en su archivo de configuración Ditutils (sección 5):

[install] install-base=$HOME install-purelib=python/lib install-platlib=python/lib.$PLAT install-scripts=python/scripts install-data=python/data

Note que estas dos no son equivalentes si usted proporciona directorio base de instalación cuando ejecuta el script de setup. Por ejemplo,

python setup.py --install-base=/tmp

Desearía instalar los módulos en /tmp/python/lib en un primer caso, y en /tmp/lib en un segundo caso. (Para el segundo caso usted probablemente quisiera proporcionar una base de instalación /tmp/python.)

Usted probablemente notó el uso de $HOME y $PLAT en el archivo de entrada en el ejemplo de configuración. Estas son variables de configuración de Distutils, que son muy parecidas a las variables de ambiente. En efecto usted puede usar variables de ambiente en los archivos config - en plataformas que tienen tal notación - pero Distutils adicionalmente define algunas variables más que pueden no estar en su ambiente, tal como $PLAT. (Y por su puesto, usted puede solo utilizar las variables de configuración proporcionadas por el Distutils en sistemas que no tienen variables de ambiente, tal como MacOs (ver la sección 5 para más detalles)

5. Distutils Configuración de Archivos.

Como se comentó anteriormente usted puede usar los archivos de configuración Distutils, para almacenar cualquier referencia de las opciones de Distutils. Esto es, cualquier opción ó comando puede ser almacenado en uno de los dos o tres archivos de configuración (dependiendo de la plataforma), los cuales pueden ser consultado antes de que el comando de línea sea analizado. Esto significa que los archivos de configuración pueden sobrescribir los valores por default, y los comandos de línea pueden sobrescribir los archivos de configuración. Además, si los archivos de configuración múltiple aplican, los valores de los archivos de inicio “early” son sobrescritos por los archivos finales “later”.

5.1. Localización y nombres de los archivos de configuración.

La localización y os nombres de los archivos de configuración varia dependiendo de la plataforma. En Unix, los tres archivos de configuración (en el orden que son procesados) son:

Tipo de Archivo Localización y nombre del Archivo Nota

S

Sistema prefix/lib/pythonver/distutils/pydistutils.cf (1 1

g Personal $HOME/.pydistutils.cfg Local setup.cfg

En Windows, los archivos de configuración son:

Tipo de Localización y nombre del Archivo Archivo Sistema prefix\Lib\distutils\pydistutils.cfg Personal %HOME\pydistutils.cfg Local setup.cfg

Y en MacOs, son:

Tipo de Localización y nombre del Archivo Archivo Sistema prefix:Lib:distutils:pydistutils.cfg Personal N/A Local setup.cfg

Notas:

(1) Estrictamente hablando los archivos de configuración del sistema, están en el directorio donde Distutils está instalado; esto ocurre en Unix bajo con 1.6. y versiones posteriores. En Python 1.5.2 Distutils normalmente es instalado en prefix/lib/site-packages/python 1.5/distutils, así los archivos de configuración del sistema pueden ser puestos ahí con Pitón 1.5.2.

(2) Sobre Unix, si la variable de ambiente HOME no está definida, el directorio de usuario puede ser definido por la función estándar getpwuido, del módulo pwd.

(3) 1.e. En el actual directorio (usualmente donde está localizado el script de setup). (4) (Ver la nota (1)). Bajo Python 1.6 y versiones posteriores el “prefijo de instalación”

(installation preix) de Python por default es C:\Python, así la configuración del archivo de sistema normalmente es C:\Python\Lib\distutils\pydistutils.cfg. Bajo Python 1.5.2. el prefijo por default fue C:\Progam Files\Python, y los Distutils no fueron parte de la librería estándar - así el archivo de configuración del sistema sería C:\Program Files\Python\distutiIs.cfg en una instalación estándar de Python 1.5.2 bajo Windows.

(5) En Windows. La variable de ambiente HOME no está definida, ningún archivo de configuración personal puede ser usado ó encontrado. (En otras palabras, en Windows los Distutils no hacen ninguna suposición sobre el directorio origen “home” ).

(6) (Ver las notas 1 y 4). El prefijo de instalación por default es Python, así bajo Python 1.6 y versiones posteriores este es normalmente Python:Lib:distutils:pydistutils.cfg.

5.2 Sintaxis de los archivos config.

Todos los archivos de configuración Distutils tienen la misma sintaxis. Los archivos config están agrupados en secciones; hay una sección para cada comando de Distutils, además de una sección global para las opciones globales. Cada una de las secciones consiste de una opción por línea, especificada como option=value.

Por ejemplo, el siguiente es un archivo config que obliga a todos los comando a correr paso a paso por default

[global] verbose=O

Si este es instalado como el archivo config del sistema, este afectara todos los procesos de cualquier modulo distribuido de Python para cualquier usuario del actual sistema. SI este es instalado como su archivo personal config (sobre el sistema que soporte al mismo), este solo afectara los módulos distribuidos procesados por usted. Y si este es usado como el setup.cfg para un módulo distribuido en particular, este solo afecta esta distribución.

Usted podría sobrescribir los directorios por default “build base” y hacer que el comando build siempre obliga a reconstruir todos los archivos, con las siguientes líneas:

[build] build-base=blib force= 1

que corresponden a los argumentos de la línea de comandos

python setup.py build --build-base=blib --force

excepto que incluir el comando build en la línea de comando significa el comando puede ser ejecutado. Incluir un comando en particular en el archivo config no tiene tal implicación, esto significa que si el comando es ejecutado, la opción en el archivo config aplica. (O si algún otro comando que es derivado del archivo config es ejecutado, este usara los valores definidos en el archivo config.)

Usted puede encontrar la lista completa de opciones para cualquier comando usando la opción -help, e.g.:

python setup.py build -help

y usted puede encontrar la lista completa de opciones globales usando el comando --help sin ningún comando:

python setup.py --help

6. Utilización del interprete de Python.

6.1. Llamar al Intérprete.

En Unix, el intérprete de Python se suele instalar como /usr/local/bin/pitón en aquellas máquinas donde esté disponible. En Windows, se instala en el directorio Archivos de Programa. Poner este directorio en el path hace posible arrancar tecleando el intérprete de órdenes la sentencia:

python

Como la elección del directorio donde reside el intérprete es una opción de instalación, es posible que se halle en otros lugares. Teclear un carácter EOF o fin de fichero (Control -D en Unix, Control-2 en Dos o Windows) en el intérprete causa la salida del intérprete con estado cero. Si eso no funciona, se puede salir del intérprete tecleando las siguientes ordenes: "import sys; sys.exit()". Las opciones de edición de la línea de ordenes no son muy destacables. En Unix, es posible que quien instaló el intérprete de su sistema, incluyera soporte para la biblioteca GNU 'readline', que permite la edición de líneas más elaborada y recuperación de órdenes anteriores. El modo más rápido de ver si hay soporte de edición de líneas es teclear Contro-P en cuanto aparece el intérprete. Si no sale nada o sale P, no está disponible la edición de líneas y sólo se puede utilizar la tecla de borrado para borrar el último carácter tecleado. El intérprete funciona como el intérprete de órdenes de Unix: cuando se le llama con la entrada estándar conectada a un dispositivo tty, lee y ejecuta las órdenes interactivamente; cuando se le da un nombre de fichero como argumento o se le da un fichero como entrada estándar, lee y ejecuta un guion desde ese fichero. Un tercer modo de arrancar el intérprete es "python -c orden [argumento] ...", que ejecuta las sentencias de orden, de forma análoga a la opción -c de la línea de órdenes. Como las sentencias de Python suelen contener espacios u otros caracteres que la línea de órdenes considera especiales, lo mejor es encerrar orden entre dobles comillas por completo. Observa que hay una diferencia entre "python fichero" y "python <fichero". En el caso de la redirección, las solicitudes de entrada del programa, tales como llamadas a input() y raw-input(), se satisfacen desde fichero. Como este fichero ya se ha leído hasta el final antes de empezar la ejecución del programa, el programa se encuentra un EOF (fin de fichero) inmediatamente. En el caso del nombre de fichero como argumento, las solicitudes de entrada son satisfechas desde lo que esté conectado a la entrada estándar (esto suele ser lo deseado). Cuando se utiliza un fichero de guión, a veces es útil ejecutar el guión y entrar en modo interactivo inmediatamente después. Esto se consigue pasando -i como argumento, antes del nombre del guion (esto no funciona sí el guion se lee desde la entrada estándar, por la misma razón indicada en el párrafo anterior).

6.1 .I Traspaso de Argumentos

El intérprete pasa el nombre del guion y los argumentos, si los conoce, mediante la variable sys.argv, que es una lista de cadenas. Su longitud es al menos uno (cuando no hay guion y no hay argumentos, sys.argv[O] es una cadena vacía). Cuando el guion es I-'

(es decir, la entrada estándar), sys.argv[O] vale I-'. Cuando se utiliza -c orden, sys.argv[O] vale ' 4 . Las opciones tras -c orden no las utiliza el intérprete Python, sino que quedan en sys.argv para uso de la orden.

6.1.2 Modo interactivo

Cuando se leen órdenes desde una tty, se dice que el intérprete está en modo interactivo. En este modo, espera a la siguiente orden con el indicadorprincipal, que suelen ser tres signos 'mayor' (">>>" ). Para las líneas adicionales, se utiliza el indicador secundario, por omisión tres puntos ("... 'I). El intérprete muestra un mensaje de bienvenida con su número de versión e información de derechos de copia, antes de mostrar el primer indicador, por ejemplo:

python Python 1.5.2b2 (#I, Feb 28 1999, 00:02:06) [GCC 2.8.11 on sunos5 Copyright 1991 -1 995 Stichting Mathematisch Centrum, Amsterdam >>>

Las líneas de continuación son necesarias al introducir construcciones milti-línea. Por ejemplo, echa un vistazo a esta sentencia if:

>>> la-tierra-es-plana = 1 >>> if la-tierra-es-plana: ... print "iCuidado, que te caes!"

¡Cuidado, que te caes! ...

6.2 El Intérprete y su entorno.

6.2.1 Gestión de Errores

Cuando ocurre un error, el intérprete muestra un mensaje de error y una traza de la pila. En el modo interactivo, después vuelve al indicador principal. Si la entrada venía de un fichero, sale con un resultado distinto de cero tras mostrar la traza de la pila (las excepciones gestionadas con una sentencia except en una construcción t r y no son errores en este contexto). Existen errores no se pueden capturar que hacen que se cierre el intérprete con un resultado distinto de cero. Por ejemplo, esto ocurre con las inconsistencias internas y, en algunos casos, al quedarse sin memoria. Todos los mensajes de error se escriben en la salida de error estándar (la pantalla, sino se redirige a un fichero u otra cosa). La salida del programa se escribe en la salida estándar (que también es la pantalla, salvo en el caso mencionado antes). Si se teclea el carácter de interrupción (suele ser Control-C o DEL) en el indicador principal o secundario se cancela la entrada y se hace volver el indicador primario(1). Si se intenta interrumpir mientras se ejecuta una orden, se activa la excepción Keyboardlnterrupt, que puede ser gestionada por una construcción try.

6.2.2 Guiones ejecutables en Python.

En sistemas Unix tipo BSD, los guiones Python se pueden hacer ejecutables directamente, como guiones de línea de órdenes, poniendo la línea #! /usr/bin/env python (Suponiendo que el intérprete está en el $PATH del usuario) al principio del guion y dándole al guion permisos de ejecución. "#!'I deben ser los primeros caracteres del fichero. Observa que la almohadilla, "#', se utiliza para iniciar un comentario en Python

6.2.3 El fichero de Arranque interactivo.

AI usar Python interactivamente, suele ser útil que se ejecuten algunas órdenes estándar cada vez que se arranca el intérprete. Se puede lograr esto poniendo en la variable de entorno $PYTHONSTARTUP el nombre del fichero que contiene las órdenes de arranque. Esto se parece a la característica .profile de la línea de órdenes de Unix o al fichero autoexecbat de MS-DOS. Este fichero sólo se lee en sesiones interactivas, no cuando Python lee órdenes de un guion, ni cuando se utiliza /dev/tty como fuente explícita de órdenes (lo que hace que se comporte casi como una sesión interactiva). Estas órdenes se ejecutan en el mismo espacio nominal que las órdenes, para que los objetos definidos o m6dulos importados se puedan usar sin necesidad de cualificarlos en la sesión interactiva. También puede cambiar los indicadores principal y secundario (sys.ps1 y sys.ps2) usando este fichero. Si deseas leer un archivo de arranque adicional del directorio actual puedes programarlo así en el fichero de arranque global, es decir "if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')". Si deseas utilizar el fichero de arranque en un guion, debes hacerlo explícitamente dentro del guion:

import os nombreFich = os.environ.get('PYTH0NSTARTUP') if nombreFich and os.path.isfile(nombreFich):

execfile(nombreFich)

Notas

( 1 ) Puede haber problemas con el paquete GNU readline que impidan esto.

7. Tipos de Datos

Las siguientes secciones describen los tipos estándar compilados internamente en el intérprete. Incluyen, entre otros, tipos numericos, tipos secuencia y los propios tipos. No existe un tipo Booleano explícito, en su lugar se usan los enteros. Algunas operaciones son posibles sobre varios tipos de objeto. En particular, todos los objetos se pueden comparar, se puede comprobar si son verdaderos y se pueden convertir a cadena (con la notación ' . . . I ) . Esta última conversión es la que se usa implícitamente cuando se escribe un objeto mediante la sentencia print.

En los siguientes ejemplos, la entrada y la salida se distinguen por la presencia o ausencia de indicadores ('I>>> " y " ... 'I). Para repetir el ejemplo debe teclear todo lo que sigue al indicador, cuando aparezca el indicador. Las líneas que no empiezan por un indicador son la salida del intérprete. Observa que un indicador secundario solo en una línea indica que debe teclear una línea en blanco. Esto se utiliza para finalizar una orden multi-línea. Muchos de los ejemplos de este manual, incluidos los que se escriben interactivamente, incluyen comentarios. Los comentarios en Python empiezan por el carácter " W , y se extienden hasta el final de la línea física. Se puede iniciar un comentario al principio de una línea o tras espacio en blanco o código, pero no dentro de una constante literal.

Ejemplos: # éste es el primer comentario fiambre = 1 # y éste

# ... iy un tercero! cadena = "# Esto no es un comentario."

7.1 Números

Hay cuatro tipos numéricos: enteros normales, enteros largos, números en coma flotante y números complejos. Los enteros normales (denominados también enteros) se implementan usando long en C, lo que les da, al menos, 32 bits de precisión. Los enteros largos no tienen un límite de precisión. Los números en coma flotante se implementan usando double en C. No se puede hacer ninguna suposición sobre su precisión salvo que se conozca la máquina y el compilador con los que se trabaja. Los números complejos tienen parte real e imaginaria, implementadas ambas con double en C. Para extraer las dos partes de un número complejo z, se usa z.real y z.imag. Los números se crean mediante constantes numéricas literales o como resultado de funciones y operadores internos. Las constantes literales enteras (incluidos los números hexadecimales y octales) sin aditivos generan enteros simples. Las constantes literales enteras con un sufijo "L" o "I" generan enteros largos (¡se prefiere "L" porque "1 I" se parece demasiado a once!). Las constantes literales numéricas que contengan un punto decimal (formato sajón) o un exponente generan números de punto flotante. Si se termina un número en "j" o "J" se genera un número complejo. Python tiene soporte completo para aritmética mixta: cuando un operador aritmético binario tiene operandos de tipos numéricos diferentes, éI operando de tipo "más pequeño" se promueve al tipo del otro, donde entero es menor que entero largo, que es menor que coma flotante, que es menor que complejo. Las comparaciones entre números de diferentes tipos utilizan la misma regla. Se pueden utilizar las funciones into, long(), float(), y complex() para forzar los números a un tipo específico. Todos los tipos numéricos soportan las siguientes operaciones, por orden de prioridad ascendente

(las operaciones que comparten casilla tienen la misma prioridad y todas las operaciones numéricas tienen una prioridad mayor que las operaciones de comparación):

Notas:

(1) Por esa la lista [I ,2] se considera igual que [1.0, 2.01 y del mismo modo para las tuplas.

(2) En la división de enteros (normales o largos), el resultado es un entero. El resultado siempre se redondea hacia: 1/2 da O , (-1)/2 da -1, 14-2) da -1 y (-I)/(-2) da O. Hay que resaltar que el resultado es un entero largo si alguno de los operandos es un entero largo, independientemente del valor numérico.

(3) La conversión de coma flotante a entero (normal o largo) puede hacerse mediante redondeo o truncamiento, como en C. Consultar en las funciones floor() y ceil() del módulo math detalles sobre conversiones bien definidas.

7.1 .I Enteros

Números enteros desde un valor negativo alto hasta otro valor positivo alto. El valor máximo se conoce como MAXlNT y depende de la cantidad de bits utilizados en la computadora para representar un número. En la mayor parte de las computadoras actuales esta cantidad es de 32 bits, lo que implica que MAXINT se acerque a los dos billones.

También podemos utilizar enteros sin signo lo que incluye números positivos y el cero. De esta manera el número máximo alcanzable equivale a dos por MAXINT, o cuatro billones en una computadora de 32 bits.

Dado que el tamaño de los enteros está restringido a MAXINT, cuando sumamos dos enteros cuyo total es mayor que MAXINT, el resultado obtenido es incorrecto. En

algunos lenguajes y sistemas el resultado incorrecto igual se devuelve (usualmente con algún tipo de aviso secreto que uno puede revisar sí cree que pudo haber habido algún problema). Normalmente en estos casos se produce un error, el cual será manejado por el programa o directamente éste finalizará. Python utiliza este último sistema, mientras que TCL ha adoptado el primero. BASIC produce un error pero no provee ningún método para tratarlo (al menos yo no sé cómo).

7.1.2 Números Reales

Estos son las fracciones. Pueden representar números muy altos, más altos que MAXINT pero con menor precisión. Esto quiere decir que dos números reales que deberían ser idénticos pueden no serlo cuando son examinados por la computadora. Esto se debe a que la computadora trabaja por aproximación en los más mínimos detalles. De esta forma 4,O podría ser representado como 3,9999999 .... o 4.00000001. Estas aproximaciones son lo suficientemente precisas para la mayor parte de nuestros objetivos, pero ocasionalmente pueden ser importantes para alguna tarea específica. Recuerde esto si obtiene un resultado extraño al utilizar números reales.

7.1.3 Números Complejos o Imaginarios

Si tiene una formación científica o matemática seguramente los conocerá muy bien. Si este no es tu caso, lo más probable es que ni siquiera hayas escuchado hablar de los números complejos. De todos modos, algunos lenguajes de programación -Fortran, por ejemplo- permiten trabajar con números complejos. La mayor parte del resto, como Python, proveen una librería de funciones que permiten operar con números complejos. Y antes de que preguntes, lo mismo se aplica para las matrices.

7.1.4 Valores Booleanos - Verdadero y Falso

Solo se presentan dos valores: verdadero o falso. Algunos lenguajes manipulan los valores booleanos directamente, mientras que otros usan una convención por medio de la cual un valor numérico (en general O) representa 'falso' y otro (1 o -1) equivale a 'verdadero'.

En general se conoce a los valores booleanos como "valores de verdad" debido a que son utilizados para comprobar si algo es verdadero o falso. Por ejemplo, si escribimos un programa que realice backups de todos los archivos en un directorio, lo que debemos hacer es copiar un archivo y luego preguntarle al sistema operativo por el nombre del siguiente archivo. Si no hay más archivos responderá con una cadena vacía, entonces podremos comprobar que la cadena está vacía y guardar el resultado como un valor booleano (verdadero sí está vacía). Pronto verás cómo utilizaremos este resultado más adelante en este curso.

7.1.5 Operaciones a nivel de bit sobre enteros

Los enteros normales y largos tienen operaciones adicionales que sólo tienen sentido en cadenas de bits. Los números negativos se tratan como su valor complementario a 2 (en los enteros largos, se supone que hay suficientes bits para que la operación no desborde). La prioridad de las operaciones a nivel de bit es menor que la de las operaciones numéricas y mayor que las comparaciones. La operación unaria 'I-" tiene

la misma prioridad que las otras operaciones numéricas unarias ("+" y "-"). Esta tabla enumera los operadores a nivel de bit ordenados por prioridad ascendente (los operadores de una misma casilla tienen la misma prioridad):

Operación Resultado Notas

X l Y o a nivel de bit de x e y

Notas:

(1) En los desplazamientos n no puede ser negativo o se lanzará ValueError. (2) Un desplazamiento a la izquierda de n bits equivale a multiplicar por pow(2, n) sin

(3) Un desplazamiento a la derecha de n bits equivale a dividir por pow(2, n) sin comprobación de desbordamiento.

comprobación de desbordamiento.

7.2 Secuenciales

Hay seis tipos secuenciales: cadenas, cadenas Unicode, listas, tuplas, tampones (buffers) y objetos xrange (rangos dinámicos). Las constantes literales de cadena se escriben entre comillas simples o dobles: 'xyzzy', "frobozz". Las cadenas Unicode se parecen mucho a las cadenas, pero se especifican sintácticamente precediéndolas de un carácter "u": u'abc', u"def'. Las listas se construyen con corchetes, separando los elementos por comas: [a, b, c]. Las tuplas se construyen con el operador coma (no entre corchetes), entre paréntesis o no, aunque una lista vacía debe tener los paréntesis: a, b, c o (). Una tupla de un solo elemento debe tener una coma al final: (d,). Los tampones no tienen soporte directo de la sintaxis de Python, sino que se crean llamando a la función buffer(). Los objetos Xrange se parecen a los tampones en que no hay sintaxis específica para crearlos, sino que se crean con la función xrange(). Los tipos secuenciales cuentan con las siguientes operaciones. Las operaciones *'in'' y "not in" tienen las mismas prioridades que las operaciones de comparación. Las operaciones "+" y "*" tienen la misma prioridad que las operaciones numéricas correspondientes (1). Esta tabla enumera las operaciones de secuencias, ordenadas por prioridad ascendente (las operaciones que comparten casilla tienen la misma prioridad). En la tabla, S y t son secuencias del mismo tipo, y n, i y j son enteros:

Resultado Notas 1 si un elemento de S es igual a x, en caso contrario O 7

x not in S

la concatenación de S v t I s + t O si un elemento de S es igual a x, en caso contrario 1

I

s * n , n * S n copias de S concatenadas (2) S[ll (3) el iésimo elemento de S, contando desde O

r - l o n g i t u d menor elemento de S I M i n ( s ) e l

de S

I m a W [el mayor elemento de S I

No puede ser de otra manera, ya que el analizador es incapaz de determinar el tipo de operaciones. Los valores de n menores que O se tratan como O (lo que produce una secuencia vacía del mismo tipo que S)

Si i o j son negativos, el índice es relativo al final de la cadena, es decir, se sustituye por len(s) + i o len(s) + j . Se advierte que -0 sigue siendo O. El corte de S desde i hasta j se define como la secuencia de elementos con índice k tal que i <= k j . Si i o j son mayores que len(s), se debe usar len(s). Si se omite i, se usa O. Si se omite j , se usa len(s). Si i es mayor o igual que j , el corte resulta vacío.

7.2.1 Métodos de las Cadenas.

Éstos son los métodos de cadena que soportan tanto las cadenas de caracteres de 8 bit como los objetos Unicode:

capitalize () Devuelve una copia de la cadena con el primer carácter en mayúscula.

center (width)

espacios. Devuelve la cadena centrada en una cadena de longitud width. Se rellena con

count (sub[, start[, end] )

opcionales start y end se interpretan según la notación de corte. Devuelve cuántas veces aparece sub en la cadena S[start:end]. Los argumentos

encode ([encoding[,errors]]) Devuelve una versión codificada de la cadena. La codificación predeterminada es

la codificación predeterminada de cadenas. El parámetro opcional errors fija el esquema de gestión de errores. Su valor predeterminado es 'strict', que indica que los errores de codificación harán saltar ValueError. Otros valores posibles son 'ignore' (ignorar) y 'replace' (reemplazar).

endswith (suffix[, start[, end]]) Devuelve verdadero si la cadena finaliza con el sufijo suffix especificado, en caso

contrario falso. Si se da valor al parámetro opcional start, la comprobación empieza en esa posición. Si se da valor al parámetro opcional end, la comprobación finaliza en esa posición.

expandtabs ([tabsize])

espacios. Si no se indica el paso de tabulación tabsize se asume 8. Devuelve una copia de la cadena con todos los tabuladores expandidos a

find (sub[, start[, end]]) Devuelve el menor índice de la cadena para el que sub se encuentre, de tal modo

que sub quede contenido en el rango [start, end). Los argumentos opcionales start y end se interpretan según la notación de corte. Devuelve -1 si no se halla sub.

index (sub[, start[, end]]) Como find(), pero lanza ValueError si no se encuentra la subcadena.

isalnum ()

al menos un carácter. En caso contrario, devuelve falso. Devuelve verdadero si todos los caracteres de la cadena son alfanuméricos y hay

isalpha ()

menos un carácter. En caso contrario, devuelve falso. Devuelve verdadero si todos los caracteres de la cadena son alfabéticos y hay al

isdigit ()

menos un carácter. En caso contrario, devuelve falso. Devuelve verdadero si todos los caracteres de la cadena son dígitos y hay al

islower () Devuelve verdadero si todos los caracteres alfabéticos de la cadena están en

minúscula y hay al menos un carácter susceptible de estar en minúsculas. En caso contrario, devuelve falso.

isspace () Devuelve verdadero si todos los caracteres de la cadena son espacio en blanco (lo

que incluye tabuladores, espacios y retornos de carro) y hay al menos un cardcter. En caso contrario, devuelve falso.

istitle () Devuelve verdadero la cadena tiene forma de título (anglosajón) y hay al menos un

carácter. En caso contrario, devuelve falso. Se considera que una cadena tiene formato de título si todas sus palabras están en minúsculas a excepción de la primera letra de cada una, que debe ser mayúscula.

isupper () Devuelve verdadero si todos los caracteres alfabéticos de la cadena están en

mayúscula y hay al menos un carácter susceptible de estar en mayúsculas. En caso contrario, devuelve falso.

join (seq) Devuelve una cadena formada por la concatenación de todos los elementos de la

secuencia seq. Los elementos se separan por la cadena que proporciona el método. Se lanza TypeError si alguno de los elementos no es una cadena.

ljust (width) Devuelve la cadena justificada a la izquierda en una cadena de longitud width. Se

rellena la cadena con espacios. Se devuelve la cadena original si width es menor que len(s).

lower () Devuelve una copia de la cadena convertida en minúsculas.

lstrip () Devuelve una copia de la cadena con el espacio inicial eliminado.

replace (old, neM, rnaxsplifl) Devuelve una copia de la cadena en la que se han sustituido todas las apariciones

de old por new. Si se proporciona el argumento opcional rnaxsplit, sólo se sustituyen las primeras rnaxsplit apariciones.

rfind (sub [,start [,end]]) Devuelve el índice máximo de la cadena para el que se encuentra la subcadena

sub, tal que sub está contenido en cadena[start,end]. Los argumentos opcionales start y end se interpretan según la notación de corte. Devuelve -1 si no se encuentra sub.

rindex (sub[, start[, end]]) Como rfind() pero lanza ValueError si no se encuentra sub.

rjust (width) Devuelve la cadena justificada a la derecha en una cadena de longitud width. Se

rellena la cadena con espacios. Se devuelve la cadena original si width es menor que len(s).

rstrip () Devuelve una copia de la cadena con el espacio al final suprimido.

split ([sep [,rnaxsplit]]) Devuelve una lista de las palabras de la cadena, usando sep como delimitador de

palabras. Si se indica rnaxsplit, se devolverán como mucho rnaxsplit valores (el último elemento contendrá el resto de la cadena). Si no se especifica sep o es None, cualquier espacio en blanco sirve de separador.

splitlines ([keepends]) Devuelve una lista de las líneas de la cadena, dividiendo por límites de línea. No

se incluyen los caracteres limitadores en la lista resultante salvo que se proporcione un valor verdadero en keepends.

startswith (prefix[, start[, end]]) Devuelve verdadero si la cadena comienza por prefix, en caso contrario, devuelve

falso. Si se proporciona el parámetro opcional start, se comprueba la cadena que empieza en esa posición. Si se proporciona el parámetro opcional end, se comprueba la cadena hasta esa posición.

strip () Devuelve una copia de la cadena con el espacio inicial y final suprimido.

swapcase ()

viceversa. Devuelve una copia de la cadena con las mayúsculas pasadas a minúsculas y

title ()

minúsculas excepto la primera letra, que va en mayúsculas. Devuelve una versión con formato título, es decir, con todas las palabras en

translate (table[, deletechars]) Devuelve una copia de la cadena donde se han eliminado todos los caracteres de

deletechars y se han traducido los caracteres restantes según la tabla de correspondencia especificada por la cadena table, que debe ser una cadena de longitud 256.

upper o Devuelve una copia de la cadena en mayúsculas.

7.2.2 Operaciones de Formato de las cadenas

Los objetos cadena tienen una sola operación interna: el operador % con un operando izquierdo que se interpreta como una cadena de formato de la función de C sprintf() que se aplica al operando derecho, devolviéndose el resultado de la operación de formato. El argumento derecho ha de ser una tupla con un elemento por cada argumento requerido por la cadena de formato. Si la cadena requiere un solo argumento, el operando derecho puede ser una tupla de un elemento o un objeto simple. Se permiten los siguientes caracteres de formato: %, c, S, i, d, u, o, x, X, e, E, f, g, G. La anchura y la precisión pueden ser un asterisco "*I1 para especificar que un argumento entero especifica la anchura o precisión final. Es posible usar los caracteres indicadores -, +, blank, ## y O. Los especificadores de tamaño h, I o L pueden incluirse, pero no se tienen en cuenta. La conversión %S toma cualquier objeto de Python y lo convierte a cadena usando str() antes de seguir con el formato. Las marcas ANSI %p y %n no tienen soporte. Como las cadenas de Python tienen una longitud explícita, las conversiones %S no suponen que '\O' sea el final de la cadena. Por motivos de seguridad, las precisiones de coma flotante se truncan a 50; las conversiones %f para números cuyo valor absoluto exceda de le25 se sustituyen por conversiones %g (1). Cualquier otro error hace saltar una excepción. Si el operando derecho es un diccionario (o cualquier otra correspondencia), los formatos del operando derecho deben hacer referencia a una clave entre paréntesis justo detrás del carácter "%", y cada marca de formato da formato al valor correspondiente a esa clave dentro de la correspondencia derecha. Por ejemplo:

>>> cuenta = 2 >>> lenguaje = 'Python' >>> print '%(lenguaje)s tiene %(cuenta)03d tipos de comillas.' % vars()

Python tiene 002 tipos de comillas. En este caso no puede haber especificadores * en el formato (pues requieren una lista de parámetros secuencial). Se definen operaciones adicionales de cadenas en el módulo estándar string y en el módulo interno re.

Notas:

(I) Estas cantidades con bastantes arbitrarias. Su intención es evitar la impresión de cadenas interminables de dígitos sin sentido, sin evitar el uso correcto y sin tener que conocer la precisión exacta de los valores de coma flotante de una máquina particular.

7.2.3 El tipo xrange (rango dinámico)

El tipo xrange es una secuencia inmutable utilizada normalmente en bucles. La ventaja del tipo xrange es que un objeto xrange ocupa siempre la misma cantidad de memoria, independientemente del rango que represente. No hay ventajas de rendimiento claras. Los objetos xrange se comportan como las tuplas y tienen un solo método:

tolist () Devuelve un objeto lista que representa los mismos valores que el objeto xrange.

7.2.4 Tipos de secuencias mutables

Los objetos lista tienen operaciones adicionales que permiten la modificación directa del objeto. Estas operaciones estarán soportadas también por otros tipos de secuencia mutables (cuando se añadan al lenguaje). Las cadenas y las tuplas son tipos secuenciales inmutables; dichos objetos no pueden ser modificados una vez creados. Se definen las siguientes operaciones sobre tipos secuenciales mutables (x es un objeto arbitrario):

. , [s.index(x) le1 mínimo valor de i tal que S[/ ] == x

La implementación C de Python aceptaba múltiples parámetros y los juntaba en una tupla. Esto no funciona en Python 2.0. Se desaconsejaba usar esta anomalía desde Python 1.4.

Lanza una excepción si x no es un objeto lista. El método extend() es experimental y no tiene soporte de otros tipos secuenciales mutables que no sean listas. Lanza ValueError si x no se encuentra en s. El método pop() sólo funciona en los tipos lista y matriz. El argumento opcional i tiene un valor por omisión de -1, para que por omisión, se devuelve y elimine el último elemento. Los métodos sort() y reverse() modifican el propio objeto por economía de espacio al ordenar o invertir listas largas. No devuelven la lista ordenada o invertida para recordar esta peculiaridad.

(6) El método sort() tiene un argumento opcional que especifica una función de comparación de dos argumentos (elementos de las listas) que debe devolver - 1, O o 1 si el primer argumento se considera menor, igual o mayor que el segundo, respectivamente. Esto ralentiza el proceso de ordenación considerablemente. Por ejemplo, para ordenar una lista en orden inverso es mucho más rápido llamar a los métodos sort() y reverse() que usar la función interna sort() con una función de comparación que invierta la ordenación de los elementos

7.2. Tipos Correspondencias

Un objeto correspondencia hace corresponder valores de un tipo (el tipo clave) a objetos arbitrarios. Las correspondencias son objetos mutables. En la actualidad, sólo hay un tipo correspondencia estándar, el diccionario. Las claves de un diccionario pueden ser valores casi arbitrarios. Los únicos tipos de valores inaceptables como claves son los valores que contengan listas, diccionarios u otro tipo mutable que se compare por su valor, en lugar de por su identidad como objeto. Los tipos numéricos utilizados como claves obedecen a las reglas usuales de comparación: si dos números resultan iguales si se comparan (por ejemplo 1 y 1.0) se pueden usar intercambiablemente para indicar la misma entrada en el diccionario. Los diccionarios se crean colocando una lista separada por comas de pares key: value, entre llaves, por ejemplo: {'jack': 4098, 'sjoerd': 4127) o (4098: 'jack', 4127: 'sjoerd'}. Se definen las siguientes operaciones sobre correspondencias (donde a y b son correspondencias, k es una clave, y v y x son objetos arbitrarios):

(1) Lanza una excepción si k no está en la correspondencia (2) Las claves y valores se enumeran en orden definido. Si se llama a keys() y a

values() sin modificar el diccionario, las listas obtenidas se corresponderán uno a uno. Esto permite la creación de las parejas (valor, clave) con map(): "pairs= map(None,a.values(), a.keys())".

(3) b debe ser del mismo tipo que a (4) Nunca lanza una excepción si k no está en la correspondencia, sino que

devuelve x. x si no se proporciona x y k no está en la correspondencia, se devuelve None.

(5) Setdefault() es como get(), salvo que si falta k, se devuelve x y se inserta como valor correspondiente a k.

7.3 Cadenas

Además de los números, Python también sabe manipular cadenas, que se pueden expresar de diversas maneras. Se pueden encerrar entre comillas simples o dobles:

>>> 'fiambre huevos' 'fiambre huevos'

Las cadenas pueden ocupar varias líneas de diferentes maneras. Se puede impedir que el final de línea física se interprete como final de línea lógica mediante usando una barra invertida, por ejemplo:

hola = "Esto es un texto bastante largo que contiene\n\ varias líneas de texto, como si fuera C.\n\ Observa que el espacio en blanco al principio de la línea es\ significativo.\n"

print hola

mostraría lo siguiente:

Esto es un texto bastante largo que contiene varias líneas de texto, como si fuera C. Observa que el espacio en blanco al principio de la línea es significativo.

O se pueden encerrar las cadenas entre comillas triples emparejadas: """ o "l. No es necesario poner barra invertida en los avances de línea cuando se utilizan comillas triples; serán incluidos en la cadena.

Print """ Uso: cosilla [OPCIONES] -h Mostrar este mensaje de uso -H Nombreservidor Nombre del servidor al que conectarse ,11111

presenta:

Uso: cosilla [OPCIONES]

-H Nombreservidor Nombre del servidor al que conectarse -h Mostrar este mensaje de uso

El intérprete muestra los resultados de las operaciones con cadenas como se escriben a la entrada: Entre comillas y con las comillas y otros caracteres raros escapados por barras invertidas, para mostrar el valor exacto. La cadena se encierra entre comillas dobles si contiene una comilla simple y no contiene comillas dobles, si no, se encierra entre comillas simples (se puede utilizar print para escribir cadenas sin

comillas ni secuencias de escape). Se puede concatenar cadenas (pegarlas) con el operador + y repetirlas con *:

>>> palabra = 'Ayuda' + 'Z >>> palabra 'AyudaZ'

'<AyudaZAyudaZAyudaZAyudaZAyudaZ>' >>> ' 4 + palabra*5 + '>'

7.4 Cadenas Unicode

A partir de Python 2.0, el programador dispone de un nuevo tipo de datos para almacenar datos de texto: el objeto Unicode. Se puede usar para almacenar y manipular datos Unicode (consulte http://www.unicode.org) y se integra bien con los objetos de cadena existentes, proporcionando conversiones automáticas si se da el caso. La codificación Unicode tiene la ventaja de proporcionar un ordinal para cada sistema de escritura utilizado en textos antiguos y modernos. Anteriormente, había sólo 256 ordinales para los caracteres escritos y se solía asociar los textos a una página de códigos, que hacía corresponder los ordinales con los caracteres escritos. Esto llevaba a una gran confusión, especialmente en lo relativo a la internacionalización (comúnmente escrito

+ 18 caracteres + "n") del software. Unicode resuelve estos problemas definiendo una página de códigos única para todos los sistemas de escritura. Crear cadenas Unicode en Python es tan simple como crear cadenas normales:

lli18nll _ _ !till

>>> u'Muy buenas' u'Muy buenas'

La "u" minúscula frente a la comilla indica que se ha de crear una cadena Unicode. Si deseas incluir caracteres especiales dentro de la cadena, lo puedes hacer mediante la codificación Unicode-Escape de Python. El siguiente ejemplo muestra cómo:

>>> u'Muy\\u0020buenas' u'Muy buenas'

La secuencia de escape u0020 indica que se ha de insertar el carácter Unicode con ordinal hexadecimal 0x0020 (el espacio) en la posición indicada. El resto de los caracteres se interpretan utilizando sus ordinales respectivos directamente como ordinales Unicode. Como ocurre que los primeros 256 ordinales de Unicode coinciden con la codificación estándar Latin-I utilizada en muchos países occidentales(l), el proceso de introducir Unicode se ve muy simplificado. Para los expertos, existe también un modo en bruto, como para las cadenas normales. Se debe preceder la cadena con una "r" minúscula para que Python utilice la codificación En bruto-Unicode-Escape. Sólo aplicará la conversión citada uXXXX si hay un número impar de barras invertidas frente a la "u".

>>> ur'Muy\u0020buenas' u'Muy buenas' >>> ur'Muy\\u0020buenas' u'Muy\\\\u0020buenas'

El modo en bruto es útil cuando hay que meter gran cantidad de barras invertidas, como en las expresiones regulares. Además de estas codificaciones estándar, Python proporciona un conjunto completo de modos de crear cadenas Unicode basándose en una codificación conocida. La función interna unicode() proporciona acceso a todos los codecs (codificadores / decodificadores) Unicode registrados. Algunas de las codificaciones más conocidas a las que pueden convertir estos codecs son Latin-?, ASCII, UTF-8 y UTF-76. Los últimos dos son codificaciones de longitud variable que permiten almacenar caracteres Unicode de 8 o 16 bits. Python usa UTF-8 como codificación por defecto. Esto se hace patente cuando se presentan cadenas Unicode o se escriben en ficheros.

>>>

u'\344\366\374' >>> str(u"aijij") '\303\244\303\266\303\274'

Si tienes datos en una codificación específica y quieres obtener la correspondiente cadena Unicode a partir de ellos, puedes usar la función interna unicode() con el nombre de la codificación como segundo argumento.

>>> unicode('\303\244\303\266\303\274','UTF-8') u'\344\366\374'

Para reconvertir la cadena Unicode a una cadena con la codificación original, los objetos proporcionan un método encode().

>>> u"aoü".encode('UTF-8') '\303\244\303\266\303\274'

Notas: (1) En España, Windows utiliza WinANSI, que es muy parecido a Latin-l. MS-DOS

y Windows en consola utiliza una codificación propia, denominada OEM a veces, en la que no coinciden algunos caracteres, en concreto las letras acentuadas). Supongo que esto coincide con otros países en los que se habla castellano. Las distribuciones de Linux actuales (2000) utilizan Latin -1 siempre.

7.5 Listas

Python utiliza varios tipos de datos compuestos, que se utilizan para agrupar otros valores. El más versátil es la lista, que se puede escribir como una lista de valores (elementos) separada por comas entre corchetes. Los elementos de una lista no tienen que ser todos del mismo tipo.

>>> a = ['fiambre', 'huevos', 100, 12341

['fiambre', 'huevos', 100, 12341 >>> a

Como los indices de las cadenas, los indices de una lista empiezan en cero. Las listas también se pueden cortar, concatenar, etc.:

>>> a[O] 'fiambre' >>> a[3] 1234 >>> a[-21 1 O0 >>> a[l :- I ] ['huevos', 1001 >>> a[:2] + ['bacon', 2*2] ['fiambre', 'huevos', 'bacon', 41 >>> 3*a[:3] + ['¡Hey!'] ['fiambre', 'huevos', 100, 'fiambre', 'huevos', 100, 'fiambre', 'huevos', 100, 'i Hey!']

>>> a ['fiambre', 'huevos', 100, 12341 >>> a[2] = a[2] + 23 >>> a ['fiambre', 'huevos', 123, 12341

Se puede asignar a u n corte, lo que puede hasta cambiar el tamaño de la lista:

>>> # Reemplazar elementos: ... a[O:2] = [I, 121 >>> a [I, 12, 123, 12341 >>> # Quitar elementos: ... a[0:2] = [I >>> a [ I 23, 12341 >>> # Insertar cosas: ... a [ l : l ] = ['puaj', 'xyzzy'] >>> a [ 123, 'puaj', 'xyzzy', 12341 >>> a[:O] = a # Insertarse (una copia) al principio de ella misma >>> a [ 123, 'puaj', 'xyzzy', 1234, 123, 'puaj', 'xyzzy', 12341 La función interna len() se aplica también a las listas: >>> len(a) 8

Es posible anidar listas (crear listas que contienen otras listas), por ejemplo:

>>> P[11[01 2 >>> p[lJ.append('xtra') # Consulte la sección 5.1 >>> p [ I , [2, 3, 'xtra'], 41 >>> q [2, 3, 'xtra']

7.6 Variables

Los datos son almacenados en la memoria de la computadora. Podemos comparar este proceso con las casillas de correo donde se colocan las cartas. Uno podría colocar una carta en cualquier casilla, pero si estas no tienen una etiqueta que las identifique, resultará prácticamente imposible recuperar la carta. Para seguir con la comparación, las variables son las etiquetas de las casillas en la memoria de la computadora. Ahora ya conocemos qué son los datos, pero ¿qué podemos hacer con ellos? Desde el punto de vista de la programación podemos crear instancias de los datos (organizados en objetos) y asignarlas a variables. Una variable es una referencia a un área específica de la memoria de la computadora donde se guardan los datos. En algunos lenguajes de programación la variable debe coincidir con el tipo de dato al cual apunta. En BASIC, por ejemplo, declaramos una variable de cadena agregándole el signo $ al final del nombre:

DIM MICADENA$ MICADENA$ = "Esta es una cadena"

En este ejemplo DIM MICADENA$ crea la referencia y especifica el espacio para almacenar la cadena (y sabemos que se trata de una cadena por el signo $). La línea MICADENA$ = "Esta es ..." define los datos y los coloca en el espacio de la memoria denominado MICADENA$. De forma similar declaramos un entero mediante el signo ?Lo al final del nombre:

DIM MIENTERO% MIENTERO% = 7

En Python y en Tcl una variable adquiere el tipo de datos que se le asigna por primera vez y lo mantendrá durante el programa, avisándonos si intentamos mezclar los datos de manera extraña, tal como sumar una cadena a un número (¿Recuerda el ejemplo que vimos del mensaje de error?). Es posible cambiar el tipo de datos de una variable en Python reasignando la variable.

>>> q = 7 >>> print 2*q 14 >>> q = "Siete" >>> print 2*q Sietesiete

Notemos que inicialmente la variable q apuntaba al número 7 y mantuvo este valor hasta que reasignamos la variable con el valor "Siete". De esta manera las variables en Python mantienen cualquier tipo de datos siendo posible modificar la referencia hacia otro tipo de datos simplemente reasignando la variable. Cuando se produce la reasignación el

dato original se pierde y Python lo borrará de la memoria (salvo que se lo recupere en otra variable). A esto se denomina "recolección de basura". (Esto puede compararse con el empleado del correo que cada tanto revisa las casillas y retira aquellos paquetes que carecen de información de destino. Si nadie los reclama ni es posible encontrar a su dueño, los paquetes son incinerados.)

7.7 Otros tipos Internos

En Python hay otras clases de Objetos. La mayoría de ellos cuenta con una o dos operaciones.

7.7.1 Módulos

La única operación especial de un módulo es el acceso a sus atributos: m.name, donde m es un módulo y name accede a un nombre definido en la tabla de símbolos de m. Es posible asignar valores a los atributos de un módulo (la sentencia import no es, en sentido estricto, una operación sobre un objeto módulo; import blas no requiere que exista un objeto módulo denominado blas, sino una definición (externa) de un módulo denominado blas en algún lugar). Todo módulo tiene un miembro especial llamado - dict-. Es el diccionario que contiene la tabla de símbolos del módulo. Modificar este diccionario realmente cambiará la tabla de símbolos del módulo, pero no es posible la asignación directa al atributo -diet- (es decir, se puede escribir m.-dict-['a'] = 1, que define m.a con valor 1, pero no se puede escribir m.-dict- = {}. Los módulos internos se presentan así: <module 'sys' (built-in)>. Si se cargan desde un fichero, se presentan <module 'os' from '/usr/local/lib/python2.0/os.pyc'~.

7.7.2 Clases e Instancias de Clases

Consultar el capitulo 14

7.7.3 Funciones

Los objetos función se crean mediante la definición de funciones. La única operación posible sobre un objeto función es la llamada: función(lista-de-argumentos). En realidad, existen dos estilos de objetos función: las funciones internas y las definidas por el usuario. Las dos tienen la misma operación (la llamada a la función), pero la implementación es diferente y por ello existen dos tipos de objetos diferentes. La implementación añade dos atributos de sólo lectura especial: f.func-code es el objeto código de la función (ver más adelante) y f.func-globals es el diccionario utilizado como espacio nominal global de la función (lo mismo que m.-dict- donde m es el módulo en el que está definida la función).

7.7.4 Métodos

Los métodos son funciones que se invocan utilizando la notación de atributo. Hay dos estilos: los métodos internos (como append() sobre las listas) y métodos de instancias de clases. Los métodos internos se describen junto a sus tipos asociados. La

implementación añade dos atributos de sólo lectura especial a los métodos de instancias de clases: m.im-self es el objeto sobre el que actúa el método yrn.im-func es la función que implementa el método. Llamar a m(arg-7, arg-2, ..., arg-n) es completamente equivalente a llamar a m.im-func(m.im-self, arg-7, arg-2, ..., arg-n).

7.7.5 Objetos Código

La implementación utiliza los objetos código para representar código Python ejecutable "pseudo-compilado", como el cuerpo de una función. Son distintos de los objetos función porque no contienen una referencia a su entorno de ejecución global. Los objetos código se obtienen llamando a la función interna compile() y se pueden extraer de los objetos función a través de su atributo func-code. Se puede ejecutar o evaluar un objeto código pasándolo (en lugar de una cadena de código fuente) a la sentencia exec o a la función interna eval().

7.7.6 Objetos Tipo

Los objetos tipo representan los diversos tipos de objeto. El tipo de un objeto es accesible mediante la función interna type(). No hay operaciones especiales sobre los tipos. El módulo estándar types define nombres para todos los tipos internos estándar. Los tipos se muestran de este modo: <type 'int'>.

7.7.7 El objeto Nulo

Éste es el objeto devuelto por las funciones que no devuelven un valor explícito. No tiene ninguna operación especial. Existe exactamente un objeto nulo, llamado None (un nombre interno). Se muestra como None.

7.7.8 El objeto elipsis

Este objeto lo utiliza la notación de corte extendida. No tiene ninguna operación especial. Existe exactamente un objeto elipsis, llamado Ellipsis (un nombre interno). Se muestra como Ellipsis.

7.7.9 Objetos fichero

Los objetos fichero se implementan con el paquete C stdio y se pueden crear con la función interna open().También son el resultado de otras funciones y métodos internos, por ejemplo, os.popen() y os.fdopen() y el método makefile() de los objetos socket. Cuando falla una operación de ficheros por una cuestión de E/S, se lanza la excepción IOError. Esto incluye situaciones donde la operación no esté definida por cualquier motivo, como usar seek() en un dispositivo tty o intentar escribir en un fichero abierto para lectura. Los ficheros cuentan con los siguientes métodos:

close () Cerrar el fichero. No es posible escribir ni leer en un fichero cerrado. Cualquier

speracicin que requiera que el fichero esté abierto lanzará IOError si el fichero se ha cerrado. Está permitido llamar a close() más de una vez.

flush ()

Descarga el tampón interno, como la función C fflush() de stdio. Puede no tener efecto en ciertos objetos similares a los ficheros.

isatty () Devuelve verdadero si el fichero está conectado a un dispositivo tty (un terminal

interactivo de líneas de orden), en caso contrario, falso. Note: Si un objeto similar a los ficheros no está asociado a un fichero real, no debe implementar este método.

fileno () Devuelve el "descriptor de fichero" utilizado por la implementación subyacente

para solicitar operaciones E/S del sistema operativo. Puede ser útil para interfaces de bajo nivel que utilicen descriptores de ficheros, por ejemplo, el módulo fcntl o os.read() y similares. Nota: Si un objeto similar a los ficheros no tiene un descriptor de fichero, no debe implementar este método.

read ([size]) Lee como mucho size bytes del fichero (menos sí se alcanza el final del fichero

antes de obtener size bytes). Si el argumento size es negativo o no se proporciona, se leen todos los datos hasta que se acaba el fichero. Los bytes se obtienen como objeto cadena. Se obtiene una cadena vacía si se alcanza el final del fichero inmediatamente (en ciertos ficheros, como los tty, tiene sentido intentar leer tras alcanzar el final del fichero). Este método puede llamar a la función C subyacente fread() más de una vez en sus intentos de recuperar una cantidad de bytes tan cercana a size como sea posible.

readline ([size]) Lee una línea entera del fichero. Se mantiene un carácter de fin de línea en la

cadena(1) (pero puede no aparecer cuando el fichero termine en una línea incompleta). Si se proporciona el argumento size y no es negativo, actúa como tope del número de bytes devueltos (incluyendo el retorno de carro), por lo que podría devolverse una línea incompleta. Se devuelve una cadena vacía al llegar al final del fichero. Nota: A diferencia de la función C fgets() de stdio, la cadena devuelta tendrá caracteres nulos ('\O') si aparecían en el fichero de entrada.

readlines ([sizehinfl) Lee hasta el fin de fichero utilizado readline() y devuelve una lista de las líneas

leídas. Si se proporciona el argumento opcional sizehint, se leen aproximadamente sizehint bytes (probablemente un múltiplo del tamaño del tampón interno). Los objetos que implementen una interfaz de tipo fichero pueden hacer caso omiso de sizehint si no es posible la implementación eficaz.

seek (offset[, whence]) Establece la posición actual del fichero, como la función C fseek() de stdio. El

argumento whence es opcional, con un valor predeterminado de O (posicionamiento absoluto); otros valores posibles son 1 (posicionamiento relativo a la posición actual) y 2 (posicionamiento relativo al final del fichero). No hay valor de retorno.

tell () Devuelve la posición actual del fichero, como la función C ftell() de stdio.

truncate ([size])

Trunca el fichero. Si se proporciona el argumento opcional size, el fichero se trunca a (como mucho) ese tamaño. El tamaño depende de la posición actual. La disponibilidad de esta función depende de la versión del sistema operativo (por ejemplo, no todas las versiones de Unix dan soporte a esta operación).

write (str) Escribe una cadena en el fichero. No se devuelve ningún valor. Nota: Por los

efectos del taponado, la cadena puede no aparecer en el fichero hasta que se llame a los metodos flush() o close().

writelines (list) Escribe una lista de cadenas al fichero. No se devuelve ningún valor. El nombre es

paralelo a readlineso, writelines() no añade separadores de línea. Los objetos fichero también ofrecen otros atributos interesantes. No son

necesarios para los objetos de interfaz tipo fichero, pero deberían implementarse si tienen sentido en un objeto particular.

closed Booleano que indica el estado actual del objeto fichero. Es un atributo de sólo

lectura, que se cambia mediante el método close(). Puede no estar disponible en todos los objetos con interfaz tipo fichero.

mode El modo de E/S del fichero. Si se creó el fichero con la función interna open(), será

el valor del parámetro mode. Es un atributo de sólo lectura y puede no estar disponible en todos los objetos con interfaz tipo fichero.

name Si se creó el objeto fichero mediante open(), el nombre del fichero. En caso

contrario, alguna cadena que indique el origen del fichero, de la forma Y . . > ” . Es un atributo de sólo lectura y puede no estar disponible en todos los objetos con interfaz tipo fichero.

softspace Booleano que indica si se debe escribir un espacio antes de escribir otro valor al

usar la sentencia print. Las clases que intenten simular un objeto fichero deberían tener un atributo escribible softspace, que debería inicializarse a cero. Esto será automático en la mayoría de las clases implementadas en Python (se debe tener cuidado en las clases que redefinan el acceso a los atributos). Los tipos implementados en C tendrán que proporcionar un atributo softspace escribible. Nota: Este atributo no se usa para controlar la sentencia print, sino para permitir que la implementación de print lleve la cuenta de su estado interno.

Notas: (I) La ventaja de mantener el fin de línea es que se puede devolver una cadena

vacía para indicar el fin de fichero sin ambigüedad. Otra ventaja es que (cuando esto fuera relevante, por ejemplo, si se desea hacer una copia exacta del fichero al tiempo que exploras sus líneas) se sabe si la última línea del fichero termina en retorno de carro o no (sí que ocurre).

7.8 Atributos especiales

La implementación añade atributos de sólo lectura especiales a algunos objetos, si ha lugar: - dict- Un diccionario o similar que se usa para almacenar los atributos (escribibles) de un objeto. - methods- Lista de los métodos de muchos tipos de objeto internos, es decir, [].-methods- devuelve rappend', 'count', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']. - members- Similar a -methods-, pero con atributos de datos. - class- La clase a la que pertenece una instancia. - bases- La tupla de clases base de un objeto clase.

8. Estructuras de Control de Flujo

Presentamos nuestra primer estructura de control. Ordinariamente las computadoras inician con la primer línea y van hacia abajo ejecutando línea por línea. Las estructuras de control cambian el orden en que se van ejecutando las líneas ó decide si una determinada sentencia puede ser ejecutada.

8.1 While

Mostramos el uso de esta estructura de control While mediante un ejemplo.

a = O while a 5:

a = a + l print a

La salida del programa es:

(se preguntara si podría pasar algo malo si hace que su computadora se convierta en una calculadora de 5 dólares). Bien ¿qué hace el programa? :

a = O asigna el valor O a a while a < 5: valida que a < 5. La primera vez que se ejecuta esta línea el valor de a es O y es menor que I O . De esta forma las lineas:

a = a + l print a

se ejecutaran hasta que la condición a c 5 no se cumpla (a = IO).

Otro ejemplo del uso de While

a = l s = o print 'Teclee el número que quiere sumar.' print 'Teclee O para salir.' while a != O

print 'Suma Actual:',s a = input('Número? ') s = s + a

print 'Suma Total =',S

La primera vez que se ejecuta el programa Python muestra el siguiente mensaje:

File "sum.py", line 3 while a != O

A

SyntaxError: invalid syntax

Olvidamos poner el símbolo :. El mensaje de error nos dice algo acerca del problema y nos indica con el símbolo * donde piensa que está el problema. Después de que se corrige el error la salida del programa es la siguiente:

Teclee el número a sumar, Teclee O para salir. Suma Actual: O Número? 200 Suma Actual: 200 Número? -1 5.25 Suma Actual: 184.75 Número? -1 51.85 Suma Actual: 32.9 Número? 10.00 Suma Actual: 42.9 Número? O Suma Total = 42.9

Note que la línea print ‘ Suma Total = ’, S es ejecutada hasta el final. El comando While solo afecta las líneas que están indentadas después de la sentencia While. El símbolo != significa no es igual así que While a != O:, significa hasta que a sea igual O se ejecutaran líneas que están indentadas después de la sentencia While.

Ahora que tenemos la estructura While, es posible tener programas que se ejecuten por siempre. Una forma de hacer esto es escribir un programa como este:

While 1 = 1 print “Ayuda!, estoy dentro de un loop.”

Este programa mostrara Ayuda!, estoy dentro de un loop. hasta el final del universo o hasta que usted lo pare. La forma en que se para esto es con el siguiente hit! La tecla Control (o ctrl.) y la tecla ‘c’ se presionan al mismo tiempo. Esto matara el proceso.

Ejemplos.

Fibonnaci.py #Este programa calcula la secuencia Fibonacci a = O b = l count = O max-count = 20 while count < max-count:

count = count + 1 old-a = a a = b b = old-a + b print old-a,

print

Salida: O 1 123581321 345589144233377610987159725844181

Password.py

#Espera hasta que el password sea tecleado.

password = "foobar" while password != "unicorn":

print "bienvenido" password = raw-input("Password:")

Ejemplo de la ejecución:

Password:auo Password:y22 Password: password Password:aaaa Password:unicorn Bienvenido

8.2 For

Mostramos el uso de esta estructura de control FOR mediante un ejemplo.

onetoten = range( l3 for count in onetoten:

print count and the ever-present output: 1 2 3 4

La salida luce muy familiar pero la codificación del programa es diferente. La primera línea usa la función range. La función range usa dos argumentos como estos range(start,finish). start, es el número con el que se inicia la iteración, finish debe ser mayor a número de inicio (start), cuando se cumpla que el número de iteraciones sea igual al número finish el ciclo FOR termina.

Estos son unos ejemplos para mostrar lo que sucede con la función range:

>>> range( 1 , I O) [I, 2, 3, 4, 5, 6, 7, 8, 91 >>> range(-32, -20)

>>> range(5,21) [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 201 >>> range(21,5) [I

[-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -211

La siguiente línea FOR count in onetoten: usa la estructura de control FOR. Una estructura de control FOR hace la búsqueda de los valores de iteración en la lista:, la lista va desde un valor de inicio hasta un valor final. Como FOR va a traves de cada valsr en la lista este pone cada valor en la variable (count en este caso). Esto permite usar la variable dentro del ciclo FOR. Aquí mostramos otro ejemplo:

demolist = ['vida',42, 'el universo', 6,'andt,7,'todo'] for item in demolist:

print "Artículo actual es:", print item

La salida es: El Artículo actual es: vida El Artículo actual es: 42 El Artículo actual es: el universo El Artículo actual es: 6 El Artículo actual es: and El Artículo actual es: 7 El Artículo actual es: todo

Note como el ciclo FOR va a través de la lista y coloca cada artículo en la lista. Así que, ¿par que es bueno el ciclo FOR? El primer uso es ir a través de cada elemento de la lista y hacer algo con cada uno de ellos. Aquí un ejemplo rápido para sumar todos los elementos.

I = [2,4,6,8] sum = O for num in I:

print "La suma es: ",sum sum = sum + num

con una salida simple:

La suma es: 20

O podría escribir un programa para encontrar hay algún duplicado en una lista, esto se hace de la siguiente manera:

I = [4, 5, 7, 8, 9, 1,0,7,10] I.sort() prev = I[O] del I[O] for item in I:

if prev == item:

prev = item print "Duplicado de ",prev," Encontrado"

y la salida es:

Duplicado de 7 Encontrado

Ok! pero como trabajo esto? Aquí mostramos una versión especial de depuración (debugging) para que entienda:

I = [4, 5, 7, 8, 9, 1,0,7,10] print "I = [4, 5, 7, 8, 9, 1,0,7,10]","\tl:",I I.sort() print "I.sort()","\tl:",l prev = I[O] print "prev = l[O]","\tprev:",prev del I[O] print "del I[O]","\tl:",I for item in I:

if prev == item: print "Duplicado de ",prev," Encontrado"

print *'si prev == item:","\tprev:",prev,"\titem:",item prev = item print "prev = item","\t\tprev:",prev,"\titem:",item

con la salida:

I = [4, 5, 7, 8, 9, 1,0,7,10] I : [4, 5, 7, 8, 9, 1, O, 7, IO] I.sort() I: [O, 1, 4, 5, 7, 7, 8, 9, IO] prev = I[O] prev: O del I[O] I: [I, 4, 5, 7, 7, 8, 9, 101 si prev == item: prev: O item: 1 prev = item prev: 1 item: 1 si prev == item: prev: 1 item: 4 prev = item prev: 4 item: 4 si prev == item: prev: 4 item: 5 prev = item prev: 5 item: 5 si prev == item: prev: 5 item: 7 prev = item prev: 7 item: 7 Duplicado de 7 Encontrado si prev == item: prev: 7 item: 7 prev = item prev: 7 item: 7 si prev == item: prev: 7 item: 8 prev = item prev: 8 item: 8 si prev == item: prev: 8 item: 9 prev = item prev: 9 item: 9 si prev == item: prev: 9 item: 10 prev = item prev: 10 item: 10

La razón por la cual pusimos muchas sentencias "print", es para que pueda ver que es lo que está sucediendo en cada línea. El programa inicia con una aburrida lista. Esto es, que cualquier duplicado puede estar uno junto al otro. El programa entonces inicializa la variable prev. Después el primer elemento de la lista es borrado, por lo cual el primer elemento no está duplicado. Después entramos en un ciclo FOR. Cada elemento de la lista es validado para ver si es igual al anterior. Si es el caso se ha encontrado el duplicado, Entonces el valor de prev es cambiado de tal forma que, para la siguiente iteración del ciclo FOR tenga el valor del elemento previo al actual. Seguramente el 7 se estará duplicado.

8.3 IF

Mostramos el uso de esta estructura de control FOR mediante un ejemplo, un pequeño ejemplo que calcula el valor absoluto de un número.

n = input("Número? 'I) if n c O:

else: print "El valor absoluto de",n,"es",-n

print "El valor absoluto de",n,"es",n con la salida

Número? -34 El valor absoluto de -34 es 34

Número? 1 El valor absoluto de 1 es 1

Pero que es lo que hace la computadora cuando ve estas líneas de código?

n = input("Número") espera que el usuario teclee un número if n O: Si n es menor que O Python ejecuta la línea print "El valor absoluto de",n,"es",-n. De otra forma ejecuta la línea print "El valor absoluto de",n,"es",n

Mas formalmente Pitón ve cuando la expresión n O es verdadera ó falsa. Una sentencia if es seguida por un bloque de sentencias que son ejecutadas cuando la expresión es verdadera. La sentencia else es opcional después de la sentencia if. El bloque de sentencias que se encuentran después del else son ejecutadas si la sentencia if es falsa.

Hay varias validaciones que una expresión puede tener. Aquí mostramos una tabla.

operador < <= > >= -- "

I =

<>

función Menor que Menor o igual que Mayor que Mayor o igual que Igual que No igual que Otra forma de decir no igual que

Otra característica de la sentencia if es elif. elif significa que si el if original es falso y entonces la parte elif es verdadera hace ese bloque de líneas de código. Aquí un ejemplo:

a=O while a < I O :

a = a + l if a > 5:

elif a <= 7:

else:

print a," > ",5

print a," <= ",7

print "Ninguna condición fue verdadera" y la salida

1 <= 7 2 <= 7 3 <= 7 4 <= 7 5 <= 7 6 > 5 7 > 5 8 > 5 9 > 5 10 > 5

Podemos ver que la condición elif a <= 7 es validada solo cuando la condición if es falsa. La sentencia elif permite que se hagan múltiples validaciones en una solo línea.

Ejemplos

High-low.py

#Juguemos el juego de azar alto o bajo # (originalmente escrito por Josh Cogliati, mejorado por Quique)

number = 78 guess = O

while guess != number : guess = input ("Elija un número: 'I)

if guess > number : print "Muy alto"

elif guess < number : print "muy bajo"

print "Acertó" salida:

Elija un número:100 Muy alto Elija un número:50 Muy bajo Elija un número:75 Muy bajo Elija un número:87 Muy alto

Elija un nQmero:81 Muy alto Elija un nQmero:78 Acertó

9. Un primer Acercamiento

Usted debería saber como editar programas en el editor de texto, y como grabarlos en disco (disco duro ó floppy) y ejecutarlo una vez que hayan sido grabados.

9.1 Imprimiendo líneas en pantalla

El ejemplo clásico de un primer programa en cualquier lenguaje es el programa llamado Hello, World!. Así que aquí está:

print “Hello World!”

Si usted está usando la línea de comandos para ejecutar sus programas, grabe este programa como hello.py y ejecútelo como “python hello.py”.

Por otro lado si usted está trabajando en IDLE (GUI de Python) cree el programa de la siguiente manera: Elija la opción File después New. En esta ventana teclee lo siguiente:

Print “Hello, World!”

Primero grabe el programa. Elija la opción File y después la opción Save. Grabe este como “hello.py”. (Si usted quiere puede grabarlo en otro directorio distinto al directorio que tiene por default).

El siguiente paso es ejecutar el programa. Elija la opción Edit y después Run Script.

En ambos casos cuando el programa haya sido ejecutado esto es lo que se imprimirá en pantalla:

Hello World!

Ahora uno un poco más complicado.

print “Jack and Jill went up a hill” print ”to fetch a pail of water;” print ”Jack fell down, and broke his crown,” print ”and Jill came tumbling after.”

Cuando se ejecuta este programa la salida es:

Jack and Jill went up a hill to fetch a pail of water; Jack fell down, and broke his crown, and Jill came tumbling after.

La computadora mantiene la vista en cada línea, ejecuta el comando y después se va a la siguiente línea. La computadora continúa ejecutando cada comando hasta que se llegue al final del programa.

9.2 Expresiones

Aquí está otro programa.

print "2 + 2 es", 2+2 print "3 * 4 es", 3 * 4 print 100 - 1, = 100 - 1" print "(33 + 2) I 5 + 11.5 = ",(33 + 2) I 5 + 11.5

La salida en pantalla es:

2 + 2 e s 4 3 * 4 e s 1 2 99 = l o o - I (33 + 2) / 5 + 11.5 = 19.5

9.3 Hablando con los Humanos (y otros inicios inteligentes)

Por supuesto que en un programa puede estar haciendo algo complicado y puede ser que en el futuro usted no recuerde que fue lo que hizo. Para que no suceda esto el programa puede ser comentado. Un comentario es una nota que usted u otros programadores hacer para explicar que es lo que está sucediendo. Por ejemplo:

#esta es una línea de comentarios print 22.0I7.0

Note que el comentario inicia con el carácter '#'. Los comentarios son usados para indicarle a otros como leer el programa y para usted en un futuro para hacer claro lo que está complicado.

Ejemplos

Denmark.py

print "Something's rotten in the state of Denmark." print -- Shakespeare"

Salida:

Something's rotten in the state of Denmark. -- Shakespeare

School.py

#This is not quite true outside of USA # and is based on my dim memories of my younger years print "Firstish Grade" print "1 +I =",I +I print "2+4 =",2+4 print "5-2 =",5-2

print print "Thirdish Grade" print "243-23 =",243-23 print "1 2*4 =", 12*4 print "1 2/3 =", 12/3 print "1 3/3 =*',I 3/3," R ",I 3%3 print print "Junior High" print "1 23.56-62.12 =I1, 123.56-62.12 print "(4+3)*2 =",(4+3)*2 print "4+3*2 =",4+3*2 print "3**2 =",3**2 print

Salida:

Firstish Grade 1+1 = 2 2+4 = 6 5-2 = 3

Thirdish Grade

12*4 = 49 12/3 = 4 1313 = 4 R 1

243-23 = 220

Junior High

(4+3)*2 = 14 4+3*2 = 10 3**2 = 9

123.56-62.12 = 61.44

9.4 Datos de entrada

Ahora complicaremos un poco más los programas. Aquí vamos:

print "Halt!" S = raw-input("Quién va allí? ") print "Puede pasar,", S

La salida es la siguiente:

Halt Quién va allí? cadena tecleada Puede pasar, cadena tecleada

Por supuesto cuando usted ejecute el programa tendrá que teclear una cadena (cadena tecleada) debido a que se tiene la sentencia raw-input.. Cuando ejecute el programa probablemente noto como introdujo la cadena y presiono enter. Entonces el programa imprime un poco más de texto y la cadena que introdujo. Este es un ejemplo de

datos de estrada. El programa se ejecuta hasta la línea que tiene la sentencia raw-input y entonces espera a que el usuario introduzca algún dato que el programa pueda utilizar después.

Ejemplos:

Rate-times.py

#This programs calculates rate and distance problems print "Input a rate and a distance" rate = input("Rate:") distance = input("Distance:") print "Time:",distance/rate Salida: > python rate-timespy Input a rate and a distance Rate:5 Distance: 1 O Time: 2 > python rate-times.py Input a rate and a distance Rate:3.52 Distance:45.6 Time: 12.9545454545

Area.py

#Este programa calcula el perímetro y el área de un rectángulo print "Calcula la información de un rectángulo" length = input("Largo:") width = input("Ancho:") print "Area",length*width print "Perímetro",2*length+2*width

AI ejecutar el programa:

>>> python area.py

Calcula la información de un rectángulo Largo:4 Ancho:3 Area 12 Perímetro 14

>>> python area.py

Calcula la información de un rectángulo Largo:2.53 Ancho52 Area 13.1 56 Perímetro 15.46

temperature.py

#Convertir fahrenheit a celcius temp = input("Temperatura Farenheit:") print (temp-32.0)*5.0/9.0

AI ejecutar el programa:

>>> python temperature.py Temperatura Farenheit32 0.0

>>> python temperature.py Temperatura Farenheit:-40 -40.0

>>> python temperature.py Temperatura Farenheit:212 100.0

>>> python temperature.py Temperatura Farenheit:99.6 37 .O

I O . Definición de Funciones

Iniciaremos este capítulo dando un ejemplo de que es lo que deberfa hacer para entender y definir las funciones den Python.

a = 23 b = -23

if a O: a = -a

if b O: b = -b

if a == b:

else: print "El valor absoluto de", a," y 'l,b,"es el mismo"

print "El valor absoluto de a y b es diferente"

la salida:

El valor absoluto de 23 y - 23 es el mismo.

Este programa se ve muy repetitivo. (Los programadores odian repetir código). Afortunadamente Python le permite crear funciones para evitar duplicar código. Aquí tenemos el ejemplo reescrito:

a = 23 b = -23

def abs(num): if num < O:

return num nurn = -num

if abs(a) == abs(b):

else: print "El valor absoluto de", a," y ",b,"es el mismo"

print "El valor absoluto de a y b es diferente" la salida:

El valor absoluto de 23 y - 23 es el mismo.

La principal característica de este programa es la sentencia def que declara la definición de una función. La sentencia def es seguida del nombre de la función abs (en este caso). Lo siguiente es el parámetro de la función num (num es pasado desde el programa que invoca la función). Las sentencias que están después de los : son ejecutados cuando la función es ejecutada. Las sentencias son ejecutadas hasta que una de las sentencias return 6 end es encontrada. La sentencia return regresa el valor al lugar donde la función es llamada.

Note como los valores de a y b no son cambiados. Las funciones no necesariamente tienen que ser usadas para regresar valores. Por ejemplo:

def hello(): print "Hola"

def area(width,height): return width*height

def print-welcome(name): print "Bienvenido",name

hello() hello()

print-welcome("Fred") w = 4 h = 5 print "Ancho =",w,"Largo ='',h,'' Area =",area(w,h)

La salida:

Hola Hola Bienvenido Fred Ancho = 4 Largo = 5 Area = 20

Este ejemplo muestra las cosas más usadas que se pueden hacer con las funciones. Las funciones pueden usar ninguno, uno, dos ó más argumentos

Ejemplo

#define una función que calcula el factorial de un número

def factorial(n): if n c= 1:

return n*factorial(n-I) return I

print Y ! ! = ",factorial(2) print "3! = ",factorial(3) print "4! = ",factorial(4) print "5! = ",factorial(5)

La salida:

2 ! = 2 3 ! = 6 4! = 24 5! = 120

11. Estructuras de datos

Este capítulo describe con más detalle algunas cosas que ya has visto y añade algunas cosas nuevas.

11 .I Más sobre las listas

El tipo de datos "lista" tiene algunos métodos más. Éstos son todos los métodos de los objetos lista:

aPPend00 Añadir un elemento al final de una lista; es equivalente a a[len(a):] = [x]

extend(L) Extender la lista concatenándole todos los elementos de la lista indicada; es equivalente a a[len(a):] = L.

insert(¡, x) Inserta un elemento en una posición dada. El primer argumento es el índice del elemento antes del que se inserta, por lo que a.insert(0, x) inserta al principio de la lista y a.insert(len(a), x) equivale a a.append(x).

remove(x) Elimina el primer elemento de la lista cuyo valor es x. Provoca un error si no existe tal elemento.

index(x) Devuelve el índice del primer elemento de la lista cuyo valor sea x. Provoca un error si no existe tal elemento.

count(x) Devuelve el número de veces que aparece x en la lista.

SOW) Ordena ascendentemente los elementos de la propia lista (la lista queda cambiada).

reverse()

métodos de la lista: Invierte la propia lista (la lista queda cambiada).Un ejemplo que utiliza varios

>>> a = t66.6, 333, 333, 1, 1234.51 >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 3331 >>> a.index(333) 1 >>> a.remove(333) >>> a

[66.6, -1, 333, 1 , 1234.5, 3331 >>> a.reverse() >>> a

>>> a.sort() >>> a

[333, 1234.5, 1 , 333, -1, 66.61

[-I , 1, 66.6, 333, 333, 1234.51

I 1 .I .I Como usar las listas como pilas

Los métodos de las listas facilitan mucho usar una lista como una pila, en donde el último elemento añadido es el primer elemento recuperado. ("last-in, first-out", "último en llegar, primero en salir"). Para apilar un elemento, usa append(). Para recuperar el elemento superior de la pila, usa pop() sin un índice explícito. Por ejemplo:

>>> pila = [3, 4, 51 >>> pila.append(6) >>> pila.append(7) >>> pila

>>> pila.pop() 7 >>> pila [3,4, 5, 61 >>> pila.pop() 6 >>> pila.pop() 5 >>> pila

[3,4,5,6,71

13~41

1 I .I .2 Cómo usar las listas como colas

También es muy práctico usar una lista como cola, donde el primer elemento que se añade a la cola es el primero en salir ("first-in, first-out", primero en llegar, último en salir"). Para añadir un elemento al final de una cola, usa append(). Para recuperar el primer elemento de la cola, usa pop() con O de índice. Por ejemplo:

..

>>> cola = ["Eric", "John", "Michael"] >>> cola.append("Terry") # llega Terry >>> cola.append("Graham") # llega Graham >>> cola.pop(0) 'Eric' >>> cola.pop(0) 'John' >>> cola ['Michael', 'Terry', 'Graham']

1 I .I .3 Herramientas de programación funcional

Hay tres funciones internas que son muy útiles al tratar con listas: filter(), map() y reduce(). "filter(función, secuencia)" (filtrar) devuelve una secuencia (del mismo tipo, si es posible) que contiene aquellos elementos de la secuencia para los que función(elernento) resulta verdadero. Por ejemplo, para calcular algunos primos:

>>> def f(x): return x % 2 != O and x % 3 != O

>>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 231

...

"map(función, secuencia)" (transformar) llama a funcíón(e/ernento) para cada uno de los elementos de la secuencia y devuelve una lista compuesta por los valores resultantes. Por ejemplo, para calcular algunos cubos:

>>> def cubo(x): return x*x*x .. >>> map(cubo, range(1, 11)) [I, 8, 27, 64, 125, 216, 343, 512, 729, 10001

Se puede pasar más de una secuencia como parámetro. La función debe tener tantos argumentos como secuencias se le pasan y se llama a la función con el valor correspondiente de cada secuencia de entrada (o None sí una secuencia es más corta que otra). Si se pasa None como función, se utiliza la función identidad, que devuelve sus argumentos. Combinando estos dos casos especiales vemos que "map(None, lista?, lista2)" es un modo muy cómodo de convertir una pareja de listas en una lista de parejas. Por ejemplo:

>>> secuencia = range(8) >>> def cuadrado(x): return x*x

>>> map(None, secuencia, map(cuadrad0, secuencia)) [(O, O>, (1, 1 ), (2, 4), (3, 9), (4, 1 e), (5, 25), (6, 361, (7,49)1

...

"reduce(func, secuencia)" (reducir) devuelve un valor simple que se construye llamando a la función binaria func con los dos primeros elementos de la secuencia, luego con el resultado y el siguiente elemento y así sucesivamente. Por ejemplo, para calcular la suma de los números de 1 a 10:

>>> def suma(x,y): return x+y

>>> reduce(suma, range(1, 11)) 55

...

Si sólo hay un elemento en la secuencia, se devuelve su valor; si la secuencia está vacía, se lanza una excepción. Se puede pasar un tercer argumento para indicar el valor inicial. En este caso, se devuelve este valor inicial para la secuencia vacía y la función se aplica al primer elemento, luego al segundo y así sucesivamente. Por ejemplo, >>> def sum(secuencia): ... def suma(x,y): return x+y

... return reduce(suma, secuencia, O)

>>> sum(range(1, 11)) 55 >>> sum([]) O 5.1.4 LCs

Las LCs proporcionan un modo conciso de crear listas sin recurrir al uso de map(), filter() ni lambda. La definición de lista resultante tiende a ser más clara que las listas construidas con los métodos citados. Cada LC consta de una expresión seguida de una cláusula for y cero o más cláusulas for o if. La lista resultante se obtiene evaluando la expresión en el contexto de las cláusulas for e if que la siguen. Si la expresión debe dar como resultado una tupla, hay que encerrarla entre paréntesis.

>>> frutafresca = [' plátano', ' mora ', 'fruta de la pasión '1 >>> [arma.strip() for arma in frutafresca] ['plátano', 'mora', 'fruta de la pasión'] >>> vec = [2, 4, 61 >>> [3*x for x in vec] [6, 12, 181 >>> [3*x for x in vec if x > 31 [12, 181 >>> [3*x for x in vec if x 21 [I >>> [{x: x""2) for x in vec] [{2: 4}, (4: 16}, (6: 36}] >>> [[x,x**2] for x in vec] [[2, 41, [4, 161, [6, 3611 >>> [x, x**2 for x in vec] # error - se necesita un paréntesis en las tuplas

File "<stdin>", line 1 [x, x**2 for x in vec]

A

SyntaxError: invalid syntax >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)l >>> vecl = [2, 4, 61 >>> vec2 = [4, 3, -91 >>> [x*y for x in vecl for y in vec21

>>> [x+y for x in vecl for y in vec21 [8, 6, -18, 16, 12, -36, 24, 18, -541

[6, 5, -7, 8, 7, -5, 10, 9, -31

11.2 La sentencia de/

Hay un modo de eliminar un elemento de una lista dado su índice en lugar de su valor: la sentencia del. También se puede utilizar para eliminar cortes de una lista (lo que hacíamos antes asignando una lista vacía al corte). Por ejemplo: >>> a

>>> del a[O] [-I, 1, 66.6, 333, 333, 1234.51

>>> a [ I , 66.6, 333, 333, 1234.51 >>> del a[2:4] >>> a [I, 66.6, 1234.51 del se puede utilizar para eliminar variable completas: >>> del a Hacer referencia al nombre a a partir de aquí provoca un error (al menos hasta que se asigne otro valor al nombre). Veremos otros usos de del más adelante.

1 I .3 Tuplas y secuencias

Hemos visto que las listas y las cadenas tienen muchas propiedades en común, por ejemplo, el indexado y el corte. Son dos ejemplos de tipos de datos secuenciales. Como Python es un lenguaje en evolución, se pueden añadir otros tipos de datos de secuencia. Hay otro tipo de datos secuencial: la tupla. Una tupla consta de cierta cantidad de valores separada por comas, por ejemplo:

>>> t = 12345, 54321, 'i hola!'

12345 >>> t (1 2345, 54321, 'i hola!') >>> # Se pueden anidar tuplas:

>>> u ((12345, 54321, '¡hola!'), (1, 2, 3, 4, 5))

>>> t[O]

... u = t , ( 1 , 2 , 3 , 4 , 5 )

Como puedes observar, en la salida se encierran las tuplas entre paréntesis, para que las tuplas anidadas se interpreten correctamente. En la entrada los paréntesis son opcionales, aunque a menudo son necesarios (sí la tupla es parte de una expresión más compleja). Las tuplas son muy útiles: Pares de coordenadas (x,y), registros de empleados de una base de datos, etc. Las tuplas, como las cadenas, son inmutables: No es posible asignar un valor a los elementos individuales de una tupla (se puede simular el mismo efecto mediante corte y concatenación, sin embargo). También es posible crear tuplas que contengan objetos mutables, por ejemplo, listas. Un problema especial es la construcción de tuplas de O ó 1 elementos: La sintaxis tiene trucos para resolver esto. Las tuplas vacías se construyen mediante un par de paréntesis vacío y las tuplas de un solo elemento se construyen mediante el valor del elemento seguido de coma (no vale con encerrar el valor entre paréntesis). Es feo, pero funciona. Por ejemplo:

>>> vacio = () >>> singleton = 'hola', # c-- Observa la coma final >>> len(vacio) O >>> len(sing1eton) 1 >>> singleton ('hola',)

La sentencia t = 12345, 54321, 'ihola!' es un ejemplo de empaquetado de tuplas: los valores 12345, 54321 y '¡hola!' se empaquetan en una tupla. También se puede realizar la operación inversa:

Esto se llama, por supuesto, desempaquetado de secuencias. El desempaquetado de secuencias requiere que el número de variables sea igual al número de elementos de la secuencia. Observa que la asignación múltiple sólo es un efecto combinado del empaquetado de tuplas y desempaquetado de secuencias. Esto resulta un poco asimétrico, ya que el empaquetado de varios valores siempre resulta en una tupla, aunque el desempaquetado funciona para cualquier secuencia.

11.4 Diccionarios

Otro tipo de dato interno de Python que resulta útil es el diccionario. Los diccionarios aparecen a veces en otros lenguajes como "memorias asociativas" o "matrices asociativas". A diferencia de las secuencias, que se indexan mediante un rango de números, los diccionarios se indexan mediante claves, que pueden ser de cualquier tipo inmutable. Siempre se puede utilizar cadenas y números como claves. Las tuplas pueden usarse de claves si sólo contienen cadenas, números o tuplas. Si una tupla contiene cualquier objeto mutable directa o indirectamente, no se puede usar como clave. No se pueden utilizar las listas como claves, ya que las listas se pueden modificar, por ejemplo, mediante el método append() y su método extend(), además de las asignaciones de corte y asignaciones aumentadas. Lo mejor es pensar en un diccionario como en un conjunto desordenado de parejas clave: valor, con el requisito de que las claves sean únicas (dentro del mismo diccionario). Una pareja de llaves crea un diccionario vacío: {). Si se coloca una lista de parejas clave: valor entre las llaves se añaden parejas clave: valor inicial al dlr;cionario. Así es como se presentan los diccionarios en la salida (hay ejemplos dentro de poco). Las operaciones principales sobre un diccionario son las de almacenar un valor con una clave dada y las de extraer el valor partiendo de la clave. También se puede eliminar una pareja clave: valor con del. Si se introduce una clave que ya existe, el valor anterior se olvida. Intentar extraer un valor utilizando una clave no existente provoca un error. El método keys() de un objeto de tipo diccionario devuelve todas las claves utilizadas en el diccionario, en orden aleatorio (sí deseas ordenarlas, aplica el método sort() a la lista de claves). Para comprobar si una clave existe en el diccionario, utiliza el método has-key() del diccionario. He aquí un pequeño ejemplo que utiliza un diccionario:

>>> te1 = {'jack': 4098, 'sape': 4139) >>> tel['guido'] = 4127 >>> te1 {'sape': 41 39, 'guido': 4127, 'jack': 4098) >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> te1 {'guido': 41 27, 'irv': 41 27, 'jack': 4098) >>> tel. keys() ['guido', 'irv', 'jack']

>>> tel.has-key('guido') 1

11.5 Más sobre las condiciones

Las condiciones utilizadas en construcciones while e if descritas anteriormente pueden contener otros operadores, además de las comparaciones. Los operadores de comparación in (dentro de) y not in (no está dentro de) comprueban si un valor está incluido (o no) en una secuencia. Los operadores is (es) y is not (no es) comparan si dos objetos son en realidad el mismo. Esto sólo tiene importancia en los objetos mutables, como las listas. Todos los operadores de comparación tienen la misma prioridad, que es menor que la de los operadores numéricos. Se pueden encadenar las comparaciones: Por ejemplo, a b == c comprueba si a es menor que b y además si b es igual a c. Las comparaciones se pueden combinar mediante los operadores lógicos and (y) y or (o) y la salida de una comparación (o cualquier otra expresión lógica) se puede negar mediante not (no). Todos éstos tienen menor prioridad que los operadores de comparación. Entre ellos, not tiene la prioridad más elevada y or la más baja, por lo que A and not B or C equivale a (A and (not B)) or C. Por supuesto, se pueden utilizar paréntesis para expresar un orden de operación concreto. Los operadores lógicos and y or se denominan operadores de atajo: Sus argumentos se evalúan de izquierda a derecha y la evaluación se interrumpe tan pronto como queda determinado el valor de salida. Por ejemplo, si A tiene un valor de verdadero pero B es falso, A and B and C no evalúa el valor de la expresión C. En general, el valor devuelto por un operador de atajo, cuando se utiliza como valor en general y no como valor lógico, es el último argumento evaluado. Es posible asignar el resultado de una comparación u otra expresión lógica a una variable. Por ejemplo:

>>> cadenal, cadena2, cadena3 = ", 'Trondheim', 'Hammer Dance' >>> non-null = cadenal or cadena2 or cadena3 >>> non-null 'Trondheim'

Observa que en Python, al contrario que en C, no puede haber asignación dentro de una expresi6n. Los programadores en C pueden quejarse de esto, pero evita una causa común problemas hallados en los programas en C: teclear = en una expresión en la que se quería decir ==.

11.6 Comparación entre secuencias y otros tipos

Los objetos de secuencia se pueden comparar con otros objetos del mismo tipo de secuencia. La comparación utiliza ordenación lexicogrdfica: Primero se comparan los dos primeros elementos, si estos difieren ya está determinado el valor de la comparación, si no, se comparan los dos elementos siguientes de cada secuencia y, así sucesivamente, hasta que se agota alguna de las dos secuencias. Si alguno de los elementos que se compara es éI mismo una secuencia, se lleva a cabo una comparación lexicográfica anidada. Si todos los elementos son iguales, se considera que las secuencias son iguales. Si una de las secuencias es igual a la otra truncada a partir de cierto elemento, la secuencia más corta de las dos es la menor. La ordenación lexicográfica para las cadenas utiliza el orden de los códigos ASCII de sus caracteres. He aquí ejemplos de comparaciones entre secuencias del mismo tipo:

Observa que es legal comparar objetos de tipos diferentes. El resultado es determinístico pero arbitrario: los tipos se ordenan por su nombre. De este modo, una lista siempre es menor que una cadena, una cadena siempre es menor que una tupla, etc. Los valores numéricos de tipos diferentes se comparan por su valor num&rico, por lo que O es igual a 0.0, etc. (las reglas de comparación entre objetos de tipos diferentes no son fiables. Pueden cambiar en versiones futuras del lenguaje.)

12. Módulos

Si sales del intérprete de Python y vuelves a entrar, las definiciones que hayas hecho (funciones y variables) se pierden. Por ello, si quieres escribir un programa algo más largo, será mejor que utilices un editor de texto para preparar la entrada del intérprete y ejecutarlo con ese fichero como entrada. Esto se llama crear un guion. Según vayan creciendo los programas, puede que quieras dividirlos en varios ficheros para facilitar el mantenimiento. Puede que también quieras utilizar una función que has escrito en varios programas sin tener que copiar su definición a cada programa. Para lograr esto, Python tiene un modo de poner definiciones en un fichero y utilizarlas en un guion o en una instancia interactiva del intérprete. Tal fichero se llama módulo; las definiciones de un m6dulo se pueden importar a otros m6dulos o al m6dulo principal (la colección de variables accesible desde un guion ejecutado desde el nivel superior y en el modo de calculadora). Un módulo es un fichero que contiene definiciones y sentencias Python. El nombre del fichero es el nombre del módulo con el sufijo.py. Dentro de un módulo, el nombre del módulo (como cadena) es accesible mediante la variable global -name-. Por ejemplo, utiliza tu editor de texto favorito para crear un fichero llamado fibo.py en el directorio actual, con el siguiente contenido:

# Módulo de los números de Fibonacci

def fib(n): # escribir la serie de Fibonacci hasta n a, b = O, I while b c n:

print b, a, b = b, a+b

def fib2(n): # devolver la serie de Fibonacci hasta n resultado = 0 a, b = O, 1 while b c n:

resultado.append(b) a, b = b, a+b

return resultado

Ahora entra en el intérprete de Python e importa este módulo con la siguiente orden:

>>> import fib0

Esto no introduce los nombres de las funciones definidas en fib0 directamente en la tabla de símbolos actual; sólo introduce el nombre del módulo fibo. Utilizando el nombre del módulo puedes acceder a las funciones:

>>> fibo.fib(lOO0) 1 1 2 3 5 8 1321 345589144233377610987 >>> fibo.fib2(100) [I, 1, 2, 3, 5, 8, 13, 21, 34, 55, 891 >>> fibo.-name- 'fi bo'

Si pretendes utilizar una función a menudo, la puedes asignar a un nombre local:

>>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 1 3 2 1 3 4 5 5 8 9 1 4 4 2 3 3 3 7 7

12.1 Más sobre los módulos

Un módulo puede contener sentencias ejecutables además de definiciones de funciones. Estas sentencias sirven para inicializar el módulo. Sólo se ejecutan la primera vez que se importa el módulo en alguna parte (En realidad, las definiciones de funciones también son 'sentencias' que se ejecutan. La ejecución introduce el nombre de la función en la tabla de símbolos global.). Cada módulo tiene su propia tabla de símbolos, que utilizan todas las funciones definidas por el módulo como tabla de símbolos global. Por ello, el autor de un módulo puede utilizar variables globales dentro del módulo sin preocuparse por conflictos con las variables globales de un usuario del módulo. Por otra parte, si sabes lo que haces, puedes tocar las variables globales de un módulo con la misma notación utilizada para referirse a sus funciones, nombreMod.nombreElem. Los módulos pueden importar otros módulos. Es una costumbre no obligatoria colocar todas las sentencias import al principio del módulo (o guion). Los nombres del módulo importado se colocan en la tabla de símbolos global del módulo (o guion) que lo importa. Existe una variación de la sentencia import que importa los nombres de un módulo directamente a la tabla de símbolos del módulo que lo importa. Por ejemplo:

>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 1 3 2 1 3 4 5 5 8 9 1 4 4 2 3 3 3 7 7

Esto no introduce el nombre del módulo del que se toman los elementos Importados en la tabla de símbolos local (por lo que, en el ejemplo, no está definido fibo). Además, existe una variación que importa todos los nombres que define un módulo:

>>> from fibo import * >>> fib(500) 1 123581321 345589144233377

Esto importa todos los nombres, excepto los que empiezan por un guion bajo (-).

12.1.1 El camino de búsqueda de módulos

Cuando se importa un módulo denominado fiambre, el intérprete busca un fichero denominado fiambre.py en el directorio actual y, luego, en la lista de directorios especificada por la variable de entorno $PYTHONPATH. Tiene la misma sintaxis que la variable de línea de órdenes $PATH de Unix, que es una lista de nombres de directorios. Cuando $PYTHONPATH no tiene ningún valor o no se encuentra el fichero, se continúa la búsqueda en un camino dependiente de la instalación. En Unix, normalmente es :/usr/local/lib/python. En realidad, se buscan los módulos en la lista de directorios dada por la variable syspath, que se inicializa desde el directorio que contiene el guion de entrada (o el directorio actual), $PYTHONPATH y el valor por omisión dependiente de la instalación. Esto permite que los programas que saben lo que hacen modifiquen o reemplacen el camino de búsqueda de módulos. Consulta la sección de Módulos estándar que aparece posteriormente. 6.1.2 Ficheros Python "Compilados" Como mejora considerable del tiempo de arranque de programas cortos que utilizan muchos módulos estándar, si existe un fichero llamado fiambre.pyc en el directorio donde se encuentra

fiambre.py, se supone que contiene una versión previamente "compilada a byte" del módulo fiambre. La fecha y hora de la versión de fiambre.py utilizada para generar fiambre.pyc se graba en fiambre.pyc y no se considera el fichero .pyc si no concuerdan. Normalmente, no hay que hacer nada para generar el fichero fiambre.pyc. Siempre que fiambre.py se compile sin errores, se hace un intento de escribir la versión compilada a fiambre.pyc. No se provoca un error si falla el intento. Si por cualquier motivo no se escribe completemente el fishero, el fichero fiambre.pyc resultante será reconocido como no válido y posteriormente ignorado. El contenido del fichero fiambre.pyc es independiente de la plataforma, por lo que se puede compartir un directorio de módulos entre máquinas de diferentes arquitecturas. Consejos para los expertos:

Cuando se llama al intérprete de Python con el indicador -0, se genera código optimizado, que se almacena en los ficheros .pyo. El optimizador actual no resulta de gran ayuda, sólo elimina sentencias assert e instrucciones SET-LINENO. Cuando se utiliza -0, todo el código de byte se optimiza. Se ignoran los ficheros .pyc y se compilan los ficheros .py a código byte optimizado.

Pasar dos indicadores -0 al intérprete de Python (-00) hace que el compilador a código byte realice optimizaciones que, en casos poco frecuentes, dan como resultado programas que no funcionan correctamente. Actualmente, sólo se eliminan las cadenas -doc- del código byte, lo que da como resultado ficheros .pyo más compactos. Como hay programas que suponen que estas cadenas están disponibles, sólo se debería utilizar esta opción con conocimiento de causa.

Un programa no se ejecuta más rápido cuando se lee de un fichero .pyc o .pyo que cuando se lee de un fichero .py. La única diferencia es el tiempo que tarda en cargarse. Cuando se ejecuta un guion dando su nombre en la línea de órdenes, nunca se escribe el código byte en un fichero .pyc o .pyo. Por ello, se puede reducir el tiempo de arranque de un guion moviendo la mayoría del código a un módulo y dejando un pequeño arranque que importa el módulo. También es posible nombrar directamente un fichero .pyc o .pyo en la línea de órdenes.

Es posible tener un módulo llamado fiambre.pyc (o fiambre.pyo si se utiliza -0) sin que exista el fichero fiambre.py en el mismo directorio. De este modo se puede distribuir una biblioteca de código de Python dificultando en cierta medida la ingeniería inversa.

El módulo compileall puede generar los ficheros .pyc (o .pyo si se utiliza -0) para todos los módulos de un directorio.

12.2 Módulos estándar

Python viene con una biblioteca de módulos estándar, descrita en un documento aparte, la Referencia de las Bibliotecas ("Referencia de las Bibliotecas" de aquí en adelante). Algunos módulos son internos al intérprete y proporcionan acceso a las operaciones que no son parte del núcleo del lenguaje pero se han incluido por eficiencia o para proporcionar acceso a primitivas del sistema operativo, como las llamadas al sistema. El conjunto de dichos módulos es una opción de configuración. Por ejemplo, el módulo amoeba sólo se proporciona en sistemas que de algún modo tienen acceso a primitivas Amoeba. Hay un módulo en particular que merece una especial atención, el módulo sys, que es siempre interno en cualquier intérprete Python. Las variables sys.psl y sys.ps2 definen las cadenas utilizadas como indicador principal y secundario:

>>> import sys

'>>> ' >>> sys.ps1

>>> sys.ps2

>>> sys.ps1 = 'C> ' C> print 'iPuaj!' i Puaj! C>

' I ...

Estas variables sólo están definidas si el intérprete está en modo interactivo. La variable sys.path es una lista de cadenas que determina el camino de búsqueda de módulos del intérprete. Se inicializa a un valor por omisión tomado de la variable de entorno $PYTHONPATH o de un valor por omisión interno, si $PYTHONPATH no tiene valor. Se puede modificar mediante operaciones de lista estándar, por ejemplo:

>>> import sys >>> sys.path.append('/ufs/guido/lib/python')

12.3 La función dit-()

La función interna dir() se utiliza para averiguar qué nombres define un módulo. Devuelve una lista de cadenas ordenada:

>>> import fibo, sys >>> dir(fibo) ['-name_', 'fib', 'fib2'1 >>> dir(sys) ['-name_', 'argv', 'builtin-module-names', 'copyright', 'exit', 'maxint', 'modules', 'path', 'psl', 'ps2', 'setprofile', 'settrace', 'stderr', 'stdin', 'stdout', 'version']

Sin argumentos, dit-() enumera la lista de nombres definidos actualmente (por ti o por el sistema):

>>> a = [ I , 2, 3, 4, 51 >>> import fibo, sys >>> fib = fibo.fib >>> dir() [I-name-', 'a', 'fib', 'fibo', 'sys']

Observa que enumera todo tipo de nombres: variables, módulos, funciones, etc. dir() no devuelve los nombres de las funciones y variables internas. Si deseas obtener esos nombres, están definidos en el módulo estándar -builtin-:

>>> import -builtin- >>> dir(-builtin-) ['AccessError', 'AttributeError', 'ConflictError', 'EOFError', 'IOError', 'ImportError', 'IndexError', 'KeyError', 'Keyboardlnterrupt', 'MemoryError', 'NameError', 'None', 'OverflowError', 'RuntimeError', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError', "name-', 'abs', 'apply', 'chr', 'cmp', 'coerce',

'compile', 'dir', 'divmod', 'eval', 'execfile', 'filter', 'float', 'getattr', 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'len', 'long', 'map', 'max', 'min', 'oct', 'open', lord', 'pow', 'range', 'raw-input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'str', 'type', 'xrange']

12.4 Paquetes

Los paquetes son un método de estructurar el espacio nominal de módulos de Python, mediante el uso de "nombres de módulos con punto". Por ejemplo, el nombre de módulo A.B hace referencia a un submódulo denominado "B" de un paquete denominado "A". Del mismo modo que el uso de módulos evita que los autores de diferentes módulos tengan que preocuparse de los nombres de variables globales de los otros, la utilización de nombres de módulo con puntos evita que los autores de paquetes multi-módulo, como NumPy o PIL (la Biblioteca de tratamiento de imagen de Python), tengan que preocuparse de los nombres de los módulos ajenos. Supón que deseas diseñar una colección de módulos (un paquete) para tratar de manera uniforme ficheros de sonido y datos de sonido. Existen muchos formatos de fichero de sonido (que se suelen distinguir por la extensión, como .wav, .aiff o .au), por lo que podrías necesitar crear y mantener una colección creciente de módulos de conversión entre los diferentes formatos. También existen muchas operaciones posibles sobre los datos de sonido (tales como mezclar, añadir eco, ecualizar o generar un efecto artificial de estereofonía), por lo que, además, estarías escribiendo una serie de módulos interminable para realizar estas operaciones. He aquí una posible estructura de tu paquete (expresado en términos de sistema de ficheros jerárquico):

Sonido/ Paquete de nivel superior - init-,py Inicializa el paquete de sonido Formatos/ Subpaquete de conversiones de formato de

ficheros - init-.py leerwav.py escriwav.py 1eeraiff.p~ escriaiff .py leerau.py escriau.py

Efectos/ Subpaquete de efectos de sonido ...

- init-.py eco.py surround.py inverso.py

Filtros/ Subpaquete de filtros ...

- init-.py ecualizador.py vocoder.py karaoke.py ...

Los ficheros -init-.py son necesarios para que Python trate los directorios como contenedores de paquetes. Se hace así para evitar que los directorios con nombres comunes,

como "test", oculten accidentalmente m6dulos válidos que aparezcan más tarde dentro del camino de búsqueda. En el caso más sencillo, -init-.py puede ser un fichero vacío, pero también puede ejecutar código de inicialización del paquete o actualizar la variable -all-, descrita posteriormente. Los usuarios del paquete pueden importar módulos individuales del paquete, por ejemplo:

import Sonido.Efectos.eco

De este modo se carga el submódulo Sonido.Efectos.eco. Hay que hacer referencia a éI por su nombre completo, por ejemplo:

Sonido.Efectos.eco.filtroeco(entrada, salida, retardo=0.7, aten=4)

Un modo alternativo de importar el submódulo es:

from Sonido.Efectos import eco

Así también se carga el submódulo eco y se hace disponible sin su prefijo de paquete, por lo que se puede utilizar del siguiente modo:

eco.filtroeco(entrada, salida, retardo=0.7, aten=4)

Y otra variación es importar la función o variable deseada directamente:

from Sonido.Efectos.eco import filtroeco

De nuevo, se carga el submódulo eco, pero se hace la función filtroeco disponible directamente:

filtroeco(entrada, salida, retardo=0.7, aten=4)

Observa que al utilizar from paquete import elemento, el elemento puede ser tanto un submódulo (o subpaquete) del paquete como cualquier otro nombre definido por el paquete, como una función, clase o variable. La sentencia import comprueba primero si el elemento está definido en el paquete. Si no, asume que es un módulo e intenta cargarlo. Si no lo consigue, se provoca una excepción ImportError. Sin embargo, cuando se utiliza la sintaxis import e/emento.sube/emento.subsube/emento, cada elemento menos el último debe ser un paquete.

El último elemento puede ser un módulo o un paquete, pero no una clase, función o variable definida en el nivel superior.

12.4.1 Import * de un paquete

Y ¿qué ocurre cuando el usuario escribe from Sonido.Efectos import *? En teoría, debería rastrearse el sistema para encontrar qué submódulos existen en el paquete e importarlos todos. Por desgracia, esta operación no funciona muy bien en las plataformas Windows y Mac, en las que el sistema de ficheros no tiene una idea muy precisa de las mayúsculas de un fichero. En estas plataformas, no hay un modo garantizado de conocer si un fichero ECO.PY debería ser importado como eco, Eco o ECO (por ejemplo, Windows 95 tiene la molesta costumbre de mostrar todos los nombres de fichero con la primera letra en mayúscula). La restricción de nombres de fichero DOS (8+3) añade otro problema para los

nombres de módulo largos. La única solución es que el autor del paquete proporcione un indice explícito del paquete. La sentencia import utiliza la siguiente convenci6n: Si el c6digo del

nombres de módulos que se deben importar cuando se encuentre from paquete import *. Depende del autor del paquete mantener la lista actualizada cuando se libere una nueva versión del paquete. Los autores del paquete pueden decidir no mantenerlo, si no es útil importar * del paquete. Por ejemplo, el fichero Sonido/Efectos/-init-.py podría contener el siguiente código:

- init-.py de un paquete define una lista llamada -all-, se considera que es la lista de

- all- = [I'eco", "surround", "inverso"]

Esto significaría que from Sonido.Efectos import * importarla los tres submdduios mencionados del paquete Sonido. Si -all- no está definido, la sentencia from Sonido.Efectos import * no importa todos los módulos del subpaquete Sonido.Efectos al espacio nominal actual. Sólo se asegura de que el paquete Sonido.Efectos ha sido importado (ejecutando posiblemente su código de inicialización), -init-.py) y luego importa cualesquiera nombres definidos en el paquete. Esto incluye cualquier nombre definido (y submódulos cargados explícitamente) por -init-.py. También incluye cualquier submódulo del paquete explícitamente importado por sentencias import anteriores, por ejemplo:

import Sonido.Efectos.eco import Sonido.Efectos.surround from Sonido.Efectos import *

En este ejemplo, los módulos eco y surround se importan al espacio nominal vigente porque están definidos en el paquete Sonido.Efectos cuando se ejecuta la sentencia from ... import (esto también funciona si está definido -all-). Observa que en general se debe evitar importar * de un módulo o paquete, ya que suele dar como resultado código poco legible. Sin embargo, se puede usar para evitar teclear en exceso en sesiones interactivas y cuando ciertos módulos estén diseñados para exportar sólo nombres que cumplan ciertas reglas. Recuerda, ¡no hay nada incorrecto en utilizar from Paquete import submódulo-concreto! De hecho, es la notación recomendada salvo que el módulo que importa necesite usar submódulos del mismo nombre de diferentes paquetes.

12.4.2 Referencias internas al paquete

Es común que los submódulos necesiten hacerse referencias cruzadas. Por ejemplo, el módulo surround podría utilizar el módulo eco. De hecho, tales referencias son tan comunes que la sentencia import busca antes en el paquete contenedor que en el camino de búsqueda de módulos estándar. Por ello, basta con que el módulo surround use import eco o from eco import filtroeco. Si el módulo importado no se encuentra en el paquete actual (el paquete del que el módulo actual es submódulo), la sentencia import busca un módulo de nivel superior con el nombre dado. Cuando se estructuran los paquetes en subpaquetes (como el paquete Sonido del ejemplo), no hay un atajo para referirse a los submódulos de los paquetes hermanos y se ha de utilizar el nombre completo del subpaquete. Por ejemplo, si el módulo Sonido.Filtros.vocoder necesita utilizar el módulo eco del paquete Sonido.Efectos, debe utilizar from Sonido.Efectos import eco.

Nota: Para mayor detalle consulte el capitulo 16. Servicios de ejecución de Python

13. Entrada y salida

Hay varios modos de presentar la salida de un programa; se pueden imprimir datos en un modo legible a los humanos o escribirlos en un fichero para uso posterior. Este capítulo explora algunas de las posibilidades.

13.1 Formato de salida mejorado

Hasta ahora hemos encontrado dos modos de escribir valores: las sentencias de expresión y la sentencia print Hay un tercer modo, utilizar el método write() de los objetos fichero, donde se puede acceder al fichero de salida estándar es accesible mediante sys.stdout. Consulta la Referencia de las bibliotecas si deseas obtener información sobre el tema. A menudo, querrás tener más control sobre el formato de la salida que escribir valores separados por espacios. Hay dos modos de dar formato a la salida: El primer modo es gestionar tú mismo las cadenas. Mediante corte y empalme de cadenas se puede generar cualquier formato. El módulo estándar string contiene operaciones útiles para ajustar cadenas a un ancho de columna dado. Esto se discutiré en breve. El segundo modo es utilizar el operador o/o con una cadena como argumento izquierdo. El operador o/o interpreta el argumento izquierdo como una cadena de formato estilo sprintf() de C, que ha de ser aplicado sobre el argumento derecho para devolver la cadena resultante del formato. Queda una cuestión, por supuesto: ¿Cómo convertir valores a cadenas? Afortunadamente, Python tiene un modo de convertir cualquier valor a cadena: pasarle la función repro o, simplemente, escribir el valor entre comillas simples invertidas ("). He aquí algunos ejemplos:

>>>x = 10 * 3.14

>>> S = 'El valor de "x" es ' + 'x' + ' e "y" vale ' + 'y' + l...' >>> print S

>>> y = 200*200

El valor de "x" es 31.4 e "y" vale 40000 ...

>>> # Las comillas invertidas funcionan sobre otros tipos, además de los números: '.. P = [x, y1 >>> ps = repr(p) >>> ps '[31.4, 400001'

>>> # Convertir a cadena añade a las cadenas comillas y barras invertidas: ... hola = 'hola, mundo\n' >>> cadhola = 'hola' >>> print cadhola

'hola, mundo\012'

>>> # El argumento de las comillas invertidas puede ser una tupla: ... 'x, y, ('fiambre', 'huevos')' "(31 -4, 40000, ('fiambre', 'huevos'))"

He aquí dos modos de escribir una tabla de cuadrados y cubos:

>>> import string >>> for x in range(1, 11): ... print string.rjust('x', 2), string.rjust('x*x', 3), ... # Observa la coma final de la línea anterior ... print string.rjust('x*x*x', 4)

1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

...

>>> for x in range(1 ,I 1): ... print '%2d %3d %4d' % (x, x*x, x*x*x)

1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

...

Observa que se ha añadido un espacio entre columnas por el modo en que funciona print: siempre añade un espacio entre sus argumentos. Este ejemplo utiliza la función string.rjust(), que ajusta a la derecha una cadena dada una anchura determinada, añadiendo espacios a la izquierda. Existen las funciones relacionadas string.ljust() y string.center(). Estas funciones no escriben nada, sólo devuelven una cadena nueva. Si la cadena de entrada es demasiado larga, no la recortan, sino que la devuelven sin cambios. Se embrollará la salida, pero suele ser mejor que falsear los valores (sí es preferible truncar la salida, siempre se puede agregar una operación de corte, como "string.Ijust(x,n)[O:n]"). Existe otra función, string.zfill(), que rellena una cadena numérica por la izquierda con ceros. Entiende de signos positivo y negativo:

>>> import string >>> string.zfill('l2', 5 ) 'O001 2' >>> string.zfill('-3.14', 7) '-003.14' >>> string.zfill('3.14159265359', 5 ) '3.141 59265359'

Usar el operador % tiene este aspecto:

>>> import math >>> print 'El valor de PI es aproximadamente %5.3f.' % math.pi

El valor de PI es aproximadamente 3.142.

Si hay más de un formato en la cadena, se ha de pasar una tupla como operando derecho, como aquí:

>>> tabla = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678j >>> for nombre, telef in tabla.items(): ... print '%-los ==> %10d' % (nombre, telef)

Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127

...

La mayoría de los formatos funcionan como en C y exigen que se pase el tipo correcto. Sin embargo, de no hacerlo así, sólo se causa una excepción y no un volcado de memoria (o error de protección general). El formato %S es más relajado: Si el argumento correspondiente no es un objeto de cadena, se convierte a cadena mediante la función interna str(). Es posible pasar * para indicar la precisión o anchura como argumento (entero) aparte. No se puede utilizar los formatos de C Yon ni %p. Si tienes una cadena de formato realmente larga que no deseas dividir, sería un detalle hacer referencia a las variables por su nombre, en vez de por su posición. Esto se logra con una extensión a los formatos de C, con el formato %(nombre)formato, por ejemplo:

>>> tabla = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678) >>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' O/O tabla Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Esto resulta particularmente práctico en combinación con la nueva función interna vats(), que devuelve un diccionario que contiene todas las variables locales.

13.2 Lectura y escritura de ficheros

open() (abrir) devuelve un objeto fichero. Se suele usar con dos argumentos: "open(nombreFichero, modo)".

>>> f=open('ItmplfichTrabajo', 'w') >>> print f copen file 'ItmpIfichTrabajo', mode 'w' at 80a0960>

El primer argumento es una cadena que contiene el nombre del fichero. El segundo argumento es otra cadena que contiene caracteres que describen el modo en que se va a utilizar el fichero. El modo puede ser 'r', cuando sólo se va a leer del fichero, 'w', si sólo se va a escribir (y si existe un fichero del mismo nombre se borra) o 'a', que abre el fichero para añadir datos. En el modo 'a', cualquier dato que se escriba en el fichero se añadirá al final de los datos existentes. El argumento de modo es opcional. Se supone 'r' si se omite. En Windows y Macintosh, al añadir 'b' al modo, el fichero se abre en modo binario, por lo que existen modos como 'rb', 'wb' y 'r+b'. Windows distingue entre ficheros de texto y binarios: los caracteres de fin de línea de los ficheros de texto se alteran ligeramente de forma automática al leer o escribir

datos. Esta modificación oculta no afecta en el caso de ficheros de texto ASCII, pero corrompe los ficheros de datos binarios, tales como ficheros JPEG o .EXE. Ten mucho cuidado de utilizar el modo binario al leer y escribir dichos ficheros (observa que el comportamiento preciso del modo de texto en Macintosh depende de la biblioteca C subyacente).

13.2.1 Métodos de los objetos fichero

El resto de los ejemplos de esta sección supondrán que se ha creado previamente un objeto fichero denominado f. Para leer el contenido de un fichero, llama a f.read(can?idad), que lee cierta cantidad de datos y los devuelve como cadena. cantidad es un argumento numérico opcional. Si se omite o es negativo, se leerá y devolverá el contenido completo del fichero. Es problema tuyo si el fichero tiene un tamaño descomunal. Si se incluye el argumento y es positivo, se leen y devuelven como máximo cantidad bytes. Si se había alcanzado el final de fichero, f.read() sólo devuelve una cadena vacía ("").

>>> f.read() 'Esto es el fichero completo.\012' >>> f.read() 11

f.readline() lee una sola línea del fichero. Se deja un carácter de cambio de línea (\n) al final de la cadena, que se omite sólo en la última línea, siempre que el fichero no termine en un salto de línea. De este modo se consigue que el valor devuelto no sea ambiguo. Si f.readline() devuelve una cadena vacía, se ha alcanzado el final del fichero, mientras que una línea en blanco queda representada por '\n', una cadena que sólo contiene un salto de línea.

>>> f.readline() 'La primera línea del fichero.\Ol2' >>> f.readline() 'La segunda línea del fichero\012' >>> f.readline() I ,

f.readlines() devuelve una lista que contiene todas las líneas de datos del fichero. Si se llama con un parámetro opcional sizehint (estimación de tamaño), lee los bytes indicados del fichero, sigue hasta completar una línea y devuelve la lista de líneas. Se suele utilizar esto para leer un fichero grande de una manera eficaz por líneas, pero sin tener que cargar en memoria el fichero entero. Todas las líneas devueltas están completas

>>> f.readlines() ['La primera línea del fichero.\012', 'La segunda línea del fichero\012']

f.write(cadena) escribe el contenido de cadena al fichero y devuelve None.

>>> f.write('Probando, probando\n')

f.tell() devuelve un entero que indica la posición actual del objeto fichero dentro del fichero, medida en bytes desde el inicio del fichero. Para cambiar la posicidn del objeto fichero se usa "f.seek(desplazamiento, desde-dónde)". La posición se calcula sumando desplazamiento a un punto de referencia, seleccionado por el argumento desde-dónde. Un desde-dónde cero mide desde el inicio del fichero, 1 utiliza la posición actual y 2 utiliza el final

del fichero como punto de referencia. desde-dónde se puede omitir, en cuyo caso se utiliza el valor cero y se mide desde el principio del fichero.

>>> f=open('/tmp/fichTrabajo', Y+') >>> f.write('0123456789abcdef) >>> f.seek(5) # Ir al 5' byte del fichero >>> f.read(1) '5' >>> f.seek(-3, 2) # Ir al 3er byte antes del final >>> f.read(1) 'd'

Cuando termines de usar un fichero, llama a f.close() para cerrarlo y liberar los recursos del sistema que utilice el fichero. Tras llamar a f.close(), fracasará cualquier intento de usar el objeto fichero.

>>> f.close() >>> f.read() Traceback (innermost last):

File "<stdin>", line 1, in ? ValueError: 110 operation on closed file

Los ficheros objeto tienen más métodos, como isatty() y truncate(), de uso menos frecuente. Consulta la Referencia de las bibliotecas si deseas ver una guía completa de los objetos fichero.

13.2.2 El módulo pickle

Es fácil escribir y leer cadenas de un fichero. Los números exigen un esfuerzo algo mayor, ya que el método read() sólo devuelve cadenas, que tendrán que pasarse a una función como string.atoi(), que toma una cadena como '123' y devuelve su valor numérico 123. Sin embargo, cuando se quiere guardar tipos de datos más complejos, como listas, diccionarios o instancias de clases, las cosas se complican bastante. Mejor que hacer que los usuarios estén constantemente escribiendo y depurando código para guardar tipos de datos complejos, Python proporciona un módulo estándar llamado picle (1). Es un módulo asombroso que toma casi cualquier objeto de Python (ihasta algunas formas de código Python!) y lo convierte a una representación de cadena. Este proceso se llama estibado. Reconstruir el objeto a partir de la representación en forma de cadena se llama desestibado. Entre el estibado y el desestibado, la cadena que representa el objeto puede ser almacenada en un fichero, en memoria o transmitirse por una conexión de red a una máquina remota. Si partes de un objeto x y un objeto fichero f previamente abierto para escritura, el modo más sencillo de estibar el objeto sólo tiene una línea de código:

pickle.dump(x, f)

Para realizar el proceso inverso, si f es un objeto fichero abierto para escritura:

x = pickle.load(f)

Existen otras variaciones de este tema, que se utilizan para estibar muchos objetos o si no se quiere escribir los datos estibados a un fichero. Se puede consultar la documentación completa de pickle en la Referencia de las bibliotecas. pickle es el método estándar para hacer

que los objetos Python se puedan almacenar y reutilizar en otros programas o futuras ejecuciones del mismo programa. El término técnico que identifica esto es objeto persistente. Como pickle se utiliza tanto, muchos autores que escriben extensiones a Python tienen cuidado de asegurarse de que los nuevos tipos de datos, tales como matrices, se estiben y desestiben de la manera adecuada.

Nota:

1 N. del T. Pickle significa conservar en formo1 o encurtir, pero lo voy a traducir como estibar. Estibar es colocar los bultos en una nave para prepararla para el viaje, lo que se adapta bastante bien a la función de pickle.

14, Clases

El mecanismo de clases de Python añade clases al lenguaje con un mínimo de sintaxis y semántica nueva. Es una mezcla de los mecanismos de clase de C++ y Modula- 3. Como en los módulos, las clases de Python no ponen una barrera absoluta entre la definición y el usuario, sino que más bien se fían de la buena educación del usuario para no "invadir la definición". Se mantienen las características más importantes con plena potencia. El mecanismo de herencia de clases permite múltiples clases base, una clase derivada puede redefinir cualquier método de sus clases base y un método puede llamar a un método de una clase base con el mismo nombre. Los objetos pueden contener una cantidad arbitraria de datos privados. En terminología C++, todos los miembros de la clase (datos incluidos) son públicos y todas las funciones miembro son virtuales. No hay constructores ni destructores especiales. Como en Modula-3, no existen abreviaturas para hacer referencia a los miembros del objeto desde sus propios métodos. La función método se declara con un primer argumento explícito que representa al objeto y que se proporciona implícitamente al llamar a la función. Como en Smalltalk, las clases son ellas mismas objetos, aunque en un sentido más amplio de la palabra: en Python, todos los tipos de datos son objetos. Esto proporciona la semántica para importar y renombrar. Sin embargo, como en C++ o en Modula3, los tipos internos no pueden ser la clase base para extensiones del usuario. Además, como en C++ y al contrario de Modula-3, la mayoría de operadores internos con sintaxis especial (operadores aritméticos, indices, etc.) se pueden redefinir en las clases.

14.1 Unas palabras sobre la terminología

A falta de una terminología universalmente aceptada para hablar de clases, haré uso ocasional de términos de Smalltalk y C++ (haría uso de términos de Modula-3, ya que la semántica orientada al objeto es más cercana a Python que la de C++, pero no espero que muchos lectores la dominen). También he notado que hay un agujero en la terminología de los lectores orientados a objetos: La palabra "objeto" en Python no significa necesariamente una instancia de una clase. Como en C++ y en Modula-3, al contrario que en Smalltalk, no todos los tipos son clases: Los tipos internos, como listas y enteros no lo son, ni siquiera algunos tipos más exóticos, como los ficheros. Sin embargo, todos los tipos de Python comparten algo de semántica común, descrita adecuadamente mediante la palabra "objeto". Los objetos tienen individualidad. Se pueden asociar múltiples nombres (y en diferentes ámbitos) al mismo objeto, lo que se conoce como "generar alias" en otros lenguajes. Esto no se aprecia a primera vista en Python y no hace falta tenerlo en cuenta cuando se trata con tipos inmutables (números, cadenas, tuplas ...). Sin embargo los alias tienen un efecto (¡buscado!) en la semántica del código Python que involucra los objetos mutables, como listas, diccionarios y la mayoría de los tipos que representan entidades externas al programa (ficheros, ventanas...). Se suele usar en beneficio del programa, ya que los alias se comportan como punteros en algunos aspectos. Por ejemplo, pasar un objeto es poco costoso, ya que la implementación sólo pasa un puntero. Si la función modifica el objeto que pasa como argumento, el que llama a la función verá los cambios. De este modo se elimina la necesidad de tener los dos mecanismos de traspaso de argumentos de Pascal.

14.2 Ámbitos y espacios nominales en Python

Antes de presentar las clases, debo contar algo sobre las reglas de alcance de Python. Las definiciones de clases realizan truquitos con los espacios nominales y se

necesita saber cómo funcionan los alcances y espacios nominales para comprender plenamente lo que ocurre. Incidentalmente, el conocimiento de este tema es útil para cualquier programador en Python avanzado. Empecemos con unas definiciones. Un espacio nominal es una correspondencia entre nombres y objetos. La mayoría de los espacios de nombres se implementan en la actualidad como diccionarios, pero eso no se nota en modo alguno (salvo por el rendimiento) y puede cambiar en el futuro. Ejemplos de espacios nominales son:

El conjunto de nombres internos (funciones como abs() y las excepciones internas). Los nombres globales de un módulo. Los nombres locales dentro de una llamada a función.

En cierto sentido, el conjunto de atributos de un objeto también forma un espacio nominal. Lo que hay que tener claro de los espacios nominales es que no existe absolutamente ninguna relación entre los nombres de diferentes espacios. Por ejemplo, dos módulos pueden definir una función "maximizar" sin posibilidad de confusión; los usuarios de los módulos deben preceder el nombre con el nombre del módulo. Por cierto, utilizo la palabra atributo para referirme a cualquier nombre que venga detrás de un punto; por ejemplo, en la expresión z.real, real es un atributo del objeto z. Hablando estrictamente, las referencias a nombres en un módulo son referencias a atributos. En la expresión nombremod.nombrefunc, nombremod es un objeto módulo y nombrefunc es atributo suyo. En este caso, resulta que existe una correspondencia directa entre los atributos del módulo y los nombres globales definidos en el módulo: ¡comparten el mismo espacio nomina(l)! Los atributos pueden ser de sólo lectura o de lectura/escritura. En este caso, es posible asignar valores a los atributos. Los atributos de los módulos son de lectura/escritura: Se puede escribir "nombremod.respuesta = 42". Los atributos de lectura/escritura se pueden borrar con la sentencia del, por ejemplo: "del nombremod.respuesta". Los espacios nominales se crean en diferentes momentos y tienen tiempos de vida diferentes. El espacio nominal que contiene los nombres internos se crea al arrancar el intérprete de Python y nunca se borra. El espacio nominal global de un módulo se crea al leer la definición del módulo. Normalmente, los espacios nominales de los módulos también duran hasta que se sale del intérprete. Las sentencias ejecutadas por el nivel superior de llamadas, leídas desde un guion o interactivamente, se consideran parte de un módulo denominado -main-, así que tienen su propio espacio nominal (los nombres internos también residen en un módulo, llamado -builtin-). El espacio nominal local de una función se crea cuando se llama a la función y se borra al salir de la función, por una sentencia "return" o si salta una excepción que la función no captura (en realidad, lo más parecido a lo que ocurre es el olvido). Por supuesto, las llamadas recursivas generan cada una su propio espacio nominal. Un Brnbifo es una región textual de un programa Python en que el espacio nominal es directamente accesible. "Directamente accesible" significa en este contexto una referencia sin calificar (sin puntos) que intenta encontrar un nombre dentro de un espacio nominal. Aunque los ámbitos se determinan estáticamente, se utilizan dinámicamente. En cualquier punto de la ejecución, existen exactamente tres ámbitos anidados (es decir, hay tres espacios nominales accesibles directamente): el ámbito interior, el primero en que se busca el nombre, que contiene los nombres locales, el ámbito medio, siguiente en la búsqueda de nombres, que contiene los nombres globales del módulo, y el ámbito externo, el último en la búsqueda, que contiene los nombres internos. Normalmente, el ámbito local hace referencia a los nombres locales de la función en curso (textualmente). Fuera de las funciones, el ámbito local hace referencia al mismo espacio nominal que el ámbito global: el espacio nominal del módulo.

Las definiciones de clases colocan otro espacio nominal en el ámbito local. Es importante darse cuenta de que los ámbitos se determinan textualmente: El ámbito global de una función definida en un módulo es el espacio nominal de este módulo, sin importar desde dónde o con qué alias se haya llamado a la función. Por otra parte, la búsqueda real de nombres se lleva a cabo dinámicamente, en tiempo de ejecución. Sin embargo, la definición del lenguaje tiende a la resolución estática de los nombres, así que ¡no te fíes de la resolución dinámica de los nombres! De hecho ya se determinan estáticamente las variables locales. Un asunto especial de Python es que las asignaciones siempre van al ámbito más interno, Las asignaciones no copian datos, simplemente enlazan nombres a objetos. Lo mismo vale para los borrados: la sentencia "del x" elimina el enlace de x del espacio nominal al que hace referencia el ámbito local. De hecho, todas las operaciones que introducen nombres nuevos utilizan el ámbito local. Particularmente, las sentencias import y las definiciones de funciones asocian el nombre del módulo o función al ámbito local. Se puede utilizar la sentencia global para indicar que ciertas variables residen en el ámbito global.

14.3 Un primer vistazo a las clases

Las clases introducen una pizca de sintaxis nueva, tres tipos de objeto nuevos y algo de semántica nueva.

14.3.1 Sintaxis de definición de clases

La forma más simple de definición de clase tiene este aspecto:

class nombreclase: <sentencia-1 >

<sentencia-N>

Las definiciones de clases, como las definiciones de funciones (sentencias def) deben ejecutarse para tener efecto (es perfectamente correcto colocar una definición de clase en una rama de una sentencia if o dentro de una función). En la práctica, las sentencias de dentro de una definición de clase serán definiciones de funciones, pero se permite otro tipo de sentencias, lo que resulta útil en algunos casos, ya veremos esto. Las definiciones de funciones interiores a la clase suelen tener una lista de argumentos un poco especial, dictada por las convenciones de llamada a método. Esto también se explica más adelante. Cuando se entra en una definición de clase, se genera un nuevo espacio nominal, que se utiliza como ámbito local; así que todas las asignaciones a variables locales caen dentro de este nuevo espacio nominal. En particular, las definiciones de funciones enlazan aquí el nombre de la nueva función. Cuando se abandona una definición de clase de manera normal (se ejecuta la última línea de su cbdigo), se crea un objeto de clase. Es, sencillamente, un envoltorio del contenido del espacio nominal creado por la definición de la clase. Se verá con más detalle en la siguiente sección. El ámbito local original (el que estaba activo cuando se entró en la definición de clase) se reinstancia y el objeto clase se enlaza con el nombre de clase dado en la cabecera de la función (en el ejemplo nombreclase).

14.3.2 Objetos clase

Los objetos de clase soportan dos tipos de operaciones: referencia a atributos e instanciación. Las referencias a atributos utilizan la sintaxis estándar que se utiliza para todas las referencias a atributos en Python: obj.nombre. Los nombres de atributos válidos son todos los nombres que estaban en el espacio nominal de la clase cuando fue creada la clase. Por lo tanto, si la definición de la clase tiene este aspecto:

class MiClase: "Simple clase de ejemplo" i = 12345 def f(x):

return 'hola, mundo'

MiC1ase.i y MiC1ase.f son referencias a atributos válidas, que devuelven un entero y un objeto método, respectivamente. También se puede asignar valores a los atributos de una clase; puedes cambiar el valor de MiC1ase.i con una asignación. d o c - es también un atributo válido, que devuelve la cadena de documentación que corresponde a la clase: "Simple clase de ejemplo". La instanciación de clases utiliza notación de función. Basta con imaginar que el objeto clase es una función sin parámetros que devuelve una instancia nueva de la clase. Por ejemplo, siguiendo con el ejemplo anterior:

x = Miclase()

crea una nueva instancia de la clase y la asigna a la variable local x. La operación de instanciación ("la llamada" a un objeto clase) genera un objeto vacío. Muchas clases prefieren generar los objetos en un estado inicial conocido. Por ello, una clase puede definir un método especial denominado -init-(), así:

def -init-(self): self.vaciar()

Cuando una clase define un método -init-(), la instanciación de clases llama automáticamente a -init-() para la instancia de clase recién creada. Así que, en el ejemplo de la Bolsa, se puede obtener una instancia de clase inicializada nueva mediante:

x = Bolsa()

Por supuesto, el método -init-() podría tener argumentos que le añadirían flexibilidad. En tal caso, los argumentos proporcionados al operador de instanciación de clase se pasan a -init-(). Por ejemplo,

>>> class Complejo: ... def -init-(self, parteReal, partelmaginaria): ... se1f.r = parteReal ... self.¡ = partelmaginaria ... >>> x = Complejo(3.0,-4.5) >>> x.r, x.i (3.0, -4.5)

14.3.3 Objetos instancia

¿Qué se puede hacer con los objetos instancia? Las únicas operaciones que entienden son las referencias a atributos. Hay dos tipos de nombres de atributo válidos. A los primeros los voy a llamar atributos de datos. Corresponden a las "variables de instancia" de Smalltalk o a los "miembros dato" de C++. No es necesario declarar los atributos de datos. Como las variables locales, aparecen por arte de magia la primera vez que se les asigna un valor. Por ejemplo, si x es una instancia de la clase MiClase creada anteriormente, el código siguiente mostrará el valor 16 sin dejar rastro:

x.contador = 1 while x.contador c IO:

print x.contador del x.contador

x.contador = x.contador * 2

El segundo tipo de referencia a atributo que entienden los objetos instancia son los métodos. Un método es una función que "pertenece a" un objeto. En Python, el término método no se limita a las instancias de una clase, ya que otros tipos de objeto pueden tener métodos también. Por ejemplo, los objetos de tipo lista tienen métodos llamados append, insert, remove, sort, etc. Sin embargo, vamos a utilizar ahora el término exclusivamente para referirnos a los métodos de objetos instancia de una clase, salvo que se indique lo contrario. Los nombres válidos de métodos de un objeto instancia dependen de su clase. Por definición, todos los atributos de una clase que son objetos función (definidos por el usuario) definen los métodos correspondientes de sus instancias. Así que, en nuestro ejemplo, x.f es una referencia a método correcta, ya que MiC1ase.f es una función, pero x.i no lo es, ya que MiC1ase.i no es una función. Pero x.f no es lo mismo que MiC1ase.f - es un objeto método, no un objeto función.

14.3.4 Objetos método

Normalmente, se llama a un método de manera inmediata, por ejemplo:

En nuestro ejemplo, esto devuelve la cadena 'hola, mundo'. Sin embargo, no es X.fO

necesario llamar a un método inmediatamente: x.f es un objeto método y se puede almacenar y recuperar más tarde, por ejemplo:

xf = x.f while 1:

print xf() mostrará "hola, mundo" hasta que las ranas críen pelo. ¿Qué ocurre exactamente cuando se llama a un método? Habrás observado que x.f() fue invocado sin argumento, aunque la definición del método f especificaba un argumento. ¿Qué le ha pasado al argumento? Desde luego, Python hace saltar una excepción cuando se llama a una función que necesita un argumento sin especificar ninguno (aunque no se utilice) ... En realidad, te puedes imaginar la respuesta: Lo que tienen de especial los métodos es que el objeto que los llama se pasa como primer argumento de la función. En nuestro ejemplo, la llamada x,f() es totalmente equivalente a MiClase.f(x). En general, llamar a un método con una lista de argumentos es equivalente a llamar a la función correspondiente con la lista de argumentos resultante de insertar el objeto del método al principio de la lista de argumentos original. Si todavía no entiendes cómo funcionan los métodos, igual te aclara

las cosas un vistazo a la implementación. Cuando se hace referencia a un atributo de una instancia que no es un atributo de datos, se busca en su clase. Si el nombre denota un atributo de clase válido que resulta ser un objeto función, se crea un objeto método empaquetando juntos (punteros hacia) el objeto instancia y el objeto función recién encontrado en un objeto abstracto: el objeto método. Cuando se llama al objeto método con una lista de argumentos, se desempaqueta de nuevo, se construye una nueva lista de argumentos a partir del objeto instancia y la lista de argumentos original y se llama al objeto función con la nueva lista de argumentos.

14.4 Cajón de sastre

[Igual habría que colocar esto con más cuidado . . . I Los atributos de datos se tienen en cuenta en lugar de los atributos método con el mismo nombre. Para evitar conflictos nominales accidentales, que podrían causar errores difíciles de rastrear en programas grandes, conviene utilizar algún tipo de convención que minimice la probabilidad de conflictos, por ejemplo, poner en mayúsculas los nombres de métodos, preceder los nombre de atributos de datos con una pequeña cadena única (o sólo un guion bajo) o usar verbos para los métodos y nombres para los atributos de datos. Los métodos pueden hacer referencia a atributos de datos tanto como los usuarios normales (los clientes) de un objeto. En otras palabras, no es posible usar las clases para implementar tipos de datos abstractos puros. De hecho, no hay nada en Python para posibilitar la ocultación de datos, todo se basa en convenciones (por otra parte, la implementación de Python escrita en C puede ocultar completamente los detalles de implementación y el control de acceso a un objeto sí es necesario, Io que pueden hacer también las extensiones a Python escritas en C). Los clientes deben utilizar los atributos de datos con cuidado. Observe que los clientes pueden añadir atributos de datos propios a una instancia de objeto sin afectar a la validez de los métodos, siempre que se eviten los conflictos de nombres. Nuevamente, ser coherente en los nombres puede ahorrarnos un montón de dolores de cabeza. No hay un atajo para hacer referencia a los atributos dato (in¡ a otros métodos!) desde los métodos. Encuentro que esto, en realidad, favorece la legibilidad de los métodos, porque así no hay manera de confundir las variables locales y las variables de la instancia cuando se repasa un método. Por convención, el primer argumento de los métodos se suele llamar self (yo mismo). No es más que una convención, el nombre self no le dice nada a Python (sin embargo, no seguir esta convención hace que tu código sea menos legible por otros programadores y no sería extraño que haya navegadores de la jerarquia de clases que suponen que la sigues). Cualquier objeto función que es atributo de una clase define un método para las instancias de esa clase. No es necesario que la definición de la función esté textualmente encerrada en la definición de la clase. Asignar un objeto función a una variable local de la clase también vale. Por ejemplo:

# Función definida fuera de la clase def fl(self, x , y):

return min(x, x+y)

class C: f = f l def g(self):

h = g return 'hola, mundo'

Ahora f, g y h son atributos de la clase C que hacen referencia a objetos función, por lo que los tres son métodos de las instancias de la clase C, siendo h exactamente

equivalente a g. Observa que esta práctica suele valer sólo para confundir al lector del programa. Los métodos pueden llamar a otros métodos utilizando los atributos método del argumento self, por ejemplo:

class Bolsa: def -init-(self):

self.datos = [I def agregar(self, x):

self.datos.append(x) def agregarDosVeces(self, x):

self.add(x) self.add(x)

Los métodos pueden hacer referencia a los nombres globales del mismo modo que las funciones normales. El ámbito global asociado a un método en un método es el módulo que contiene la definición de la clase (la clase en sí nunca se utiliza como ámbito global). Aunque es raro encontrar un buen motivo para usar un dato global en un método, hay bastantes usos legítimos del ámbito global: de momento, los métodos pueden usar las funciones y los módulos importados al ámbito global, al igual que las funciones y las clases definidas en él. Normalmente, la clase que contiene el método está definida en este ámbito global. En la siguiente sección encontraremos algunas buenas razones para que un mktodo haga referencia a su propia clase.

14.5 Herencia

Por supuesto, una característica de un lenguaje no sería digna del nombre "clase" si no aportara herencia. La sintaxis de una definición de clase derivada tiene este aspecto: class nombreClaseDerivada(nombreC1aseBase):

<sentencia-1 >

<sentencia-N>

El nombre nombreClaseBase debe estar definido en un ámbito que contenga la definición de la clase derivada. En lugar de un nombre de clase base, se permite poner una expresión. Esto es útil cuando la clase base está definida en otro módulo, por ejemplo,

class nombreClaseDerivada(nombreMod.nombreClase6ase):

La ejecución de la definición de una clase derivada se lleva a cabo del mismo modo que la clase base. Cuando se construye el objeto de la clase, se recuerda la clase base. Esto se utiliza para resolver referencias a atributos: si no se encuentra un atributo solicitado en la clase, se busca en la clase base. Esta regla se aplica recursivamente si la clase base es a su vez derivada. No hay nada especial sobre la instanciación de las clases derivadas: nombreClaseDerivada() crea una nueva instancia de la clase. Las referencias a métodos se resuelven de la siguiente manera: Se busca el atributo de la clase correspondiente, descendiendo por la cadena de clases base, si es necesario, y la referencia a método es correcta si de este modo se obtiene un objeto función. Las clases derivadas pueden redefinir métodos de sus clases base. Como los métodos no tienen

privilegios especiales al llamar a otros métodos del mismo objeto, un método de una clase base que llama a otro método definido en la misma clase base puede acabar llamando a un método de una clase derivada que lo redefina (para los programadores de C++: todos los métodos en Python son virtuales). Puede que una redefinición de método en una clase derivada quiera ampliar, en lugar de reemplazar, el método de la clase base del mismo nombre. Existe un modo sencillo de llamar al método de la clase base directamente: simplemente, utilizar "nombreClaseBase.nombreMétodo(self, argumentos)". Esto también les vale a los clientes, en ciertas ocasiones (observa que esto sólo funciona sí la clase base está definida o se ha importado directamente en el ámbito global).

14.5.1 Herencia múltiple

Python también aporta una forma limitada de herencia múltiple. Una definición de clase con múltiples clases base tiene este aspecto:

class nombreClaseDerivada(Base1, Base2, Base3): <sentencia-I >

<sentencia-N>

La única regla necesaria para explicar la semántica es la regla de resolución utilizada para las referencias a atributos de la clase. Se busca primero por profundidad y luego de izquierda a derecha. De este modo, si no se encuentra un atributo en nombreClaseDerivada, se busca en Basel, en las clases base de Basel y, si no se encuentra, en Base2, en las clases base de ésta y así sucesivamente. Para algunos parece más natural buscar en Base2 y en Base3 antes que en las clases base de Basel. Sin embargo, esto exigiría conocer si un atributo particular de Basel está definido realmente en Basel en una de sus clases base, antes de imaginarse las consecuencias de un conflicto de nombres con un atributo de la Base2. La regla de buscar primero por profundidad no diferencia entre atributos de la Basel directos y heredados. Queda claro que el uso indiscriminado de la herencia múltiple hace del mantenimiento una pesadilla, dada la confianza de Python en las convenciones para evitar los conflictos de nombre accidentales. Un problema bien conocido de la herencia múltiple es el de una clase derivada de dos clases que resulta que tienen una clase base común. A pesar de que resulta sencillo, en este caso, figurarse qué ocurre (la instancia tendrá una sola copia de las "variables de la instancia" o atributos de datos utilizada por la base común), no queda clara la utilidad de este tipo de prácticas.

14.6 Variables privadas

Se pueden utilizar, de manera limitada, identificadores privados de la clase. Cualquier identificador de la forma f i a m b r e (al menos dos guiones bajos iniciales, no más de un guion bajo final) se reemplaza textualmente ahora con - nombreClasefiambre, donde nombreclase es la clase en curso, eliminando los guiones bajos iniciales. Esta reescritura se realiza sin tener en cuenta la posición sintáctica del identificador, por lo que se puede utilizar para definir, de manera privada, variables de clase e instancia, métodos y variables globales. También sirve para almacenar variables de instancia privadas de esta clase en instancias de otras clases. Puede que se recorten los nombres cuando el nombre reescrito tendría más de 255

caracteres. Fuera de las clases o cuando el nombre de la clase consta sólo de guiones bajos, no se rescriben los nombres. La reescritura de nombres pretende dar a las clases un modo sencillo de definir métodos y variables de instancia “privados”, sin tener que preocuparse por las variables de instancia definidas por las clases derivadas ni guarrear con las variables de instancia por el código externo a la clase. Observa que las reglas de reescritura se han diseñado sobre todo para evitar accidentes; aún es posible, con el suficiente empeño, leer o modificar una variable considerada privada. Esto puede ser útil, por ejemplo, para el depurador, por lo que no se ha cerrado esta puerta falsa. Hay un pequeño fallo: la derivación de una clase con el mismo nombre que su clase base hace posible el uso de las variables privadas de la clase base. Observa que el código pasado a exec, eval() o evaIfile() no considera el nombre de la clase llamante la clase actual. Es similar al efecto de la sentencia global, cuyo efecto está, de igual manera, restringido al código de un fichero. Se aplica la misma restricción a getattro, setattro, delattr() y también cuando se hace referencia a "diet- directamente. He aquí un ejemplo de una clase que implernenta sus propios métodos -getattr- y “setattr- y almacena todos los atributos en una variable privada de manera que funciona adecuadamente en todas las versiones de Python, incluidas las anteriores a agregar esta característica: class atributosVirtuales:

- vdic = None - vdic-nombre = locals().keys()[O]

def -init-(self): self.-dict-[self.-vdic-nombre] = {>

def getattr-(self, nombre): return self.-vdic[nombre]

def -setattr-(self, nombre, valor): self.-vdic[nombre] = valor

14.7 Remates

A veces es útil tener un tipo de dato similar al “record” de Pascal o a la “struct” de C, que reúnan un par de datos con nombre. Para realizar esto, se puede usar una definición de clase vacía, por ejemplo: class Empleado:

pass

juan = Empleado() # Creación de una ficha de empleado vacía

# Rellenamos los campos de la ficha juan.nombre = ‘Juan Pérez’ juan.departamento = ‘Centro de cálculo‘ juan.sueldo = 1000

Si hay código Python que espere recibir un tipo abstracto de datos concreto, es posible pasarle una clase que emule los métodos de este tipo de dato, en lugar de la clase genuina. Por ejemplo, si disponemos de una función que da formato a unos datos de un objeto fichero, podemos definir una clase con los métodos read() y readline() que tome los datos de una cadena de almacenamiento temporal y pasar dicha clase como

argumento. Los objetos de métodos de instancia también tienen atributos: m.im-self es el objeto del cual el método es instancia y m.im-func es el objeto función correspondiente al método.

14.7.1 Las excepciones pueden ser clases

Las excepciones definidas por usuario ya no están limitadas a objetos cadena de texto; también pueden identificarse mediante clases. Utilizando estos mecanismos es posible crear jerarquías ampliables de excepciones. Hay dos formas válidas nuevas de sentencia raise:

raise Clase, instancia

raise instancia

En la primera forma, instancia debe ser una instancia de Clase o de una clase derivada de ella. La segunda forma es un atajo de:

raise instancia.-class-, instancia

Una cláusula except puede enumerar clases al igual que objetos cadena. Una clase de una cláusula except captura una excepción si es de la misma clase que la excepción que ha saltado o es de una clase base de ella (al revés no; una clase derivada no captura ninguna de sus clases base). Por ejemplo, el código a continuación mostrará B, C, D, en ese orden:

class B: pass

class C(B): pass

class D(C): pass

para c en [B, C, Dl: intente on:

raise c() except D:

print "D" except C:

print "C" except B:

print "B"

Observa que si invertimos las cláusulas ("except B" primero), se mostraría B, B, B, ya que la primera cláusula captura todas las excepciones, por ser clase base de todas ellas. Cuando se presenta un mensaje de error para una excepción sin capturar, se muestra el nombre de la clase, dos puntos, un espacio y, por último, la instancia convertida a cadena mediante la función interna str().

Nota:

1. Excepto en una cosa. Los objetos de módulo tienen un atributo de sólo lectura secreto llamado -did- que devuelve el diccionario utilizado para implementar el espacio nominal del módulo. El nombre -did- es un atributo, pero no un nombre global. Evidentemente, al utilizar esto se transgrede la abstracción de la implementación del espacio nominal, por lo que su uso debe restringirse a herramientas especiales, como depuradores póstumos.

15. Excepciones internas

Las excepciones pueden ser objetos de una clase u objetos cadena. Aunque la mayoría de las excepciones eran objetos cadena en las anteriores versiones de Python, en Python 1.5 y versiones posteriores, todas las excepciones estándar han sido convertidas en objetos de clase y se anima a los usuarios a que hagan lo propio. Las excepciones están definidas en el módulo exceptions. Nunca es necesario importar este módulo explícitamente, pues las excepciones vienen proporcionadas por el espacio nominal interno. Dos objetos de cadena distintos con el mismo valor se consideran diferentes excepciones. Esto es así para forzar a los programadores a usar nombres de excepción en lugar de su valor textual al especificar gestores de excepciones. El valor de cadena de todas las excepciones internas es su nombre, pero no es un requisito para las excepciones definidas por el usuario u otras excepciones definidas por módulos de biblioteca. En el caso de las clases de excepción, en una sentencia try con una cláusula except que mencione una clase particular, esta cláusula también gestionará cualquier excepción derivada de dicha clase (pero no las clases de excepción de las que deriva ella). Dos clases de excepción no emparentadas mediante subclasificación nunca son equivalentes, aunque tengan el mismo nombre. Las excepciones internas enumeradas a continuación pueden ser generadas por el intérprete o por funciones internas. Excepto en los casos mencionados, tienen un "valor asociado" indicando en detalle la causa del error. Este valor puede ser una cadena o tupla de varios elementos informativos (es decir, un código de error y una cadena que explica el código). El valor asociado es el segundo argumento a la sentencia raise. En las cadenas de excepción, el propio valor asociado se almacenará en la variable nombrada como el segundo argumento de la cláusula except (si la hay). En las clases de excepción, dicha variable recoge la instancia de la excepción. Si la clase de excepción deriva de la clase raíz estándar Exception, el valor asociado está disponible en el atributo args de la instancia de excepción y es probable que aparezca en otros atributos. El código de usuario puede lanzar excepciones internas. Se puede usar para comprobar un gestor de excepciones o para informar de una condición de error del mismo modo que el intérprete lanza la misma excepción. Hay que ser precavido, pues nada incluye que el código de usuario lance una excepción inadecuada. Las siguientes excepciones sólo se usan como clase base de otras excepciones.

Exception La clase base de las excepciones. Todas las excepciones internas derivan de esta

clase. Todas las excepciones definidas por usuario deberían derivarse de esta clase, aunque no es obligatorio (todavía). La función str(), aplicada a una instancia de una clase (o la mayoría de sus clases derivadas) devuelve un valor cadena a partir de sus argumentos o una cadena vacía si no se proporcionaron argumentos al constructor. Si se usa como secuencia, accede a los argumentos proporcionados al constructor (útil para compatibilidad con código antiguo). Los argumentos también están disponibles en el atributo args de la instancia, como tupla.

StandardError

deriva de la clase raíz Exception. La clase base para todas las excepciones internas excepto SystemExit. StandardError

ArithmeticError

OverflowError, ZeroDivisionError, FloatingPointError. La clase base de las excepciones lanzadas por diversos errores aritméticos:

LookupError

La clase base de las excepciones lanzadas cuando una clave o índice utilizado en una correspondencia (diccionario) o secuencia son incorrectos: IndexError, KeyError.

EnvironmentError La clase base de las excepciones que pueden ocurrir fuera del sistema Python: IOError,

OSError. Cuando se crean excepciones de este tipo con una tupla de dos valores, el primer elemento queda disponible en el atributo errno de la instancia (se supone que es un número de error) y el segundo en el atributo strerror (suele ser el mensaje de error asociado). La propia tupla está disponible en el atributo args. New in version 1.5.2. Cuando se instancia una excepción EnvironmentError con una tupla de tres elementos, los primeros dos quedan disponibles como en el caso de dos elementos y el tercero queda en el atributo filename. Sin embargo, por compatibilidad con sistemas anteriores, el atributo args contiene sólo una tupla de dos elementos de los dos primeros argumentos del constructor. El atributo filename es None cuando se cree la excepción con una cantidad de argumentos diferente de 3. Los atributos errno y strerror son también None cuando la instancia no se cree con 2 ó 3 argumentos. En este último caso, args contiene los argumentos del constructor tal cual, en forma de tupla. Las siguientes excepciones son las realmente lanzadas.

AssertionError Se lanza cuando una sentencia assert es falsa.

AttributeError

tenga referencias o asignaciones a atributos en absoluto, se lanza, TypeError.) Se lanza cuando una referencia o asignación a atributo fracasa (cuando un objeto no

EOFError Se lanza cuando las funciones internas (input() o rawwinput()) alcanzan un final de

fichero (EOF) sin leer datos. N.B.: Los métodos read() y readline() de los objetos fichero devuelven una cadena vacía al alcanzar EOF.

FloatingPointError Se lanza cuando falla una operación de coma flotante. Esta excepción siempre está

definida, pero sólo se puede lanzar cuando Python esta configurado con la opción --with-fpectl o se ha definido el símbolo WANT-SIGFPE-HANDLER en el fichero c0nfig.h.

IOError Se lanza cuando una operación de E/S (tal como una sentencia print, la función interna

open() o un método de un objeto fichero) fracasa por motivos relativos a E/S, por ejemplo, por no encontrarse un fichero o llenarse el disco. Esta clase se deriva de EnvironmentError. En la explicación anterior se proporciona información adicional sobre los atributos de instancias de excepción.

ImportError

from ... import no encuentra un nombre a importar. Se lanza cuando una sentencia import no encuentra la definición del módulo o cuando

IndexError Se lanza cuando un subíndice de una secuencia se sale del rango .Los indices de corte

se truncan silenciosamente al rango disponible. Si un índice no es un entero simple, se lanza TypeError.

KeyError

conjunto de claves existentes. Se lanza cuando no se encuentra una clave de una correspondencia (diccionario) en el

Keyboardlnterrupt Se lanza cuando el usuario pulsa la tecla de interrupción (normalmente Control-C o

DEL(1)). A lo largo de la ejecución se comprueba si se ha interrumpido regularmente. Las interrupciones ocurridas cuando una función input() o raw-input()) espera datos también lanzan esta excepción.

MemoryError Se lanza cuando una operación agota la memoria pero aún se puede salvar la situación

(borrando objetos). El valor asociado es una cadena que indica qué tipo de operación (interna) agotó la memoria. Obsérvese que por la arquitectura de gestión de memoria subyacente (la función de C malloc()), puede que el intérprete no siempre sea capaz de recuperarse completamente de esta situación. De cualquier modo, se lanza una excepción para que se pueda imprimir una traza, por si la causa fue un programa desbocado.

NameError Se lanza cuando no se encuentra un nombre local o global. Sólo se aplica a nombre no calificados. El valor asociado es el nombre no encontrado.

NotlmplementedError Esta excepción se deriva de RuntimeError. En clases base definidas por el usuario, los métodos abstractos deberían lanzar esta excepción cuando se desea que las clases derivadas redefinan este método. New in version 1.5.2.

OSError Esta clase se deriva de EnvironmentError y se usa principalmente como excepción os.error

de os. En EnvironmentError hay una descripción de los posibles valores asociados. New in version 1.5.2.

OverflowError Se lanza cuando el resultado de una operación aritmética es demasiado grande para

representarse (desbordamiento). Esto no es posible en los enteros largos (que antes que rendirse lanzarían MemoryError). Por la falta de normalización de la gestión de excepciones de coma flotante en C, la mayoría de las operaciones de coma flotante, tampoco se comprueban. En el caso de enteros normales, se comprueban todas las operaciones que pueden desbordar excepto el desplazamiento a la izquierda, en el que las aplicaciones típicas prefieren perder bits que lanzar una excepción.

RuntimeError Se lanza cuando se detecta un error que no cuadra en ninguna de las otras categorías.

El valor asociado es una cadena que indica qué fue mal concretamente. Esta excepción es mayormente una reliquia de versiones anteriores del intérprete; ya casi no se usa.

SyntaxError Se lanza Cuando el analizador encuentra un error en la sintaxis. Esto puede ocurrir en

una sentencia import, en una sentencia exec, en una llamada a la función interna eval() o input(), o al leer el guion inicial o la entrada estándar (por ejemplo, la entrada interactiva). Si se usan excepciones de clase, las instancias de esta clase tienen disponibles los atributos

filename (nombre del fichero), lineno (no de línea), offset (no de columna) y text (texto), que ofrecen un acceso más fácil a los detalles. En las excepciones de cadena, el valor asociado suele ser una tupla de la forma (mensaje, (nombreFichero, numlinea, columna, texto)). En las excepciones de clase, str() sólo devuelve el mensaje.

SystemError Se lanza cuando el intérprete encuentra un error interno, pero la situación no parece tan

grave como para perder la esperanza. El valor asociado es una cadena que indica qué ha ido mal (en términos de bajo nivel). Se debería dar parte de este error al autor o mantenedor del intérprete Python en cuestión. Se debe incluir en el informe la cadena de versión del intérprete Python (sys.version, que también se muestra al inicio de una sesión interactiva), la causa exacta del error y, si es posible, el código fuente del programa que provocó el error.

SystemExit Lanzada por la funcidn sys.exit(). Si no se captura, el interprete de Python finaliza la

ejecución sin presentar una pila de llamadas. Si el valor asociado es un entero normal, especifica el estado de salida al sistema (se pasa a la función de C exit()), Si es None, el estado de salida es cero (que indica una salida normal sin errores). En el caso de ser de otro tipo, se presenta el valor del objeto y el estado de salida será 1. Las instancias tienen un atributo code cuyo valor se establece al estado de salida o mensaje de error propuesto (inicialmente None). Además, esta excepción deriva directamente de Exception y no de StandardError, ya que técnicamente no es un error. Una llamada a sys.exit() se traduce a un error para que los gestores de limpieza final (las cláusulas finally de las sentencias try) se puedan ejecutar y para que un depurador pueda ejecutar un guion sin riesgo de perder el control. Se puede usar la función os.-exit() si es total y absolutamente necesario salir inmediatamente (por ejemplo, tras un fork() en el proceso hijo).

TypeError

inadecuado. El valor asociado es una cadena con detalles de la incoherencia de tipos. Se lanza cuando una operación o función interna se aplica a un objeto de tipo

UnboundLocalError

no se ha asignado un valor a dicha variable. Deriva de NameError. New in version 2.0. Se lanza cuando se hace referencia a una variable local en una función o método, pero

UnicodeError

de ValueError. New in version 2.0. Se lanza cuando se da un error relativo a codificaciónldescodificación Unicode. Deriva

ValueError Se lanza cuando una operación o función interna recibe un argumento del tipo correcto,

pero con un valor inapropiado y no es posible describir la situación con una excepción más precisa, como IndexError.

WindowsError Se lanza cuando se da un error específico de Windows o el número de error no

corresponde a un valor errno. Los valores errno y strerror se crean a partir de los valores devueltos por las funciones GetLastErrorO y FormatMessageO del API de plataforma de Windows. Deriva de OSError. New in version 2.0.

ZeroDivisionError

Se lanza cuando el segundo argumento de una operación de división o módulo es cero El valor asociado es una cadena que indica el tipo de operandos y la operación.

Notas:

(1) N. del T. En Windows se suele usar Control-Inter

16. Servicios de ejecución de Python

Los módulos descritos en este capítulo proporcionan un amplio rango de servicios relativos al intérprete de Python y su interacción con el entorno. He aquí una lista de estos módulos:

IL " UserDict ,. ILEmpacador de los objetos del diccionario. .......................... ......... . . .......I. .. serList lkmpacador de la lista de objetos. ..... . . . . . . . 1 ,I j p " " ~ ... " ................... ""

Empacador de los objetos string.

egistro de las funciones soportadas por pide. ............................................................................................................................................................................................ " ...............................................................................

plicación alterna a repro con limites de tamaño. .,@ 1 B I

16.1 sys -- Parámetros y funciones específicas del sistema.

Este módulo proporciona acceso a variables utilizadas por el intérprete y a funciones que interactúan estrechamente con el intérprete. Siempre está disponible.

argv La lista de argumentos de la línea de órdenes pasada a un guion Python. argv[O] es el

nombre del guion (depende del sistema operativo sí es una ruta completa o no). Si se ejecutó la orden usando la opción de línea de órdenes -c, argv[O] valdrá la cadena '-c'. Si no se pasó un nombre de guion al intérprete de Python, argv tiene longitud cero.

byteorder Un indicador del orden de byte nativo. Tendrá el valor 'big' en plataformas "big-endian"

(el byte más significativo primero) y 'little' en plataformas "little-endian" (el byte menos significativo primero). New in version 2.0.

builtin-module-names Una tupla de cadenas con los nombres de todos los módulos compilados en el

intérprete Python concreto. Esta información no está disponible de ningún otro modo; modules.keys() solo devuelve los módulos importados.

copyright

de Python. Una cadena que contiene la información de copyright (derechos de copia) del intérprete

dllhandle

exc-info () . Un entero que especifica el asa (handle) de la DLL de Python. Disponibilidad: Windows.

Esta función devuelve una tupla de tres valores que proporcionan información sobre la excepción cuya gestión está en curso. La información devuelta es específica del hilo de ejecución en curso y del marco de pila en curso. Si el marco de pila en curso no está gestionando una excepción, la información se toma del marco de pila superior (éI Ilamante) y así sucesivamente, hasta que se encuentre un marco que esté gestionando una excepción. En este contexto, "gestionando una excepción" se define como "ejecutando o habiendo ejecutado una cláusula except". Para cualquier marco de pila, sólo es accesible la información sobre la excepción gestionada más recientemente. Si no se está gestionando ninguna excepción en ningún lugar de la pila, se devuelve una tupla con tres valores None. En caso contrario, los valores devueltos son (tipo, valor, traza). Su significado es el siguiente: tipo recibe el tipo de la excepción que se está gestionando (una cadena u objeto clase); valor recibe el parámetro de la excepción (su valor asociado o el segundo argumento de raise, que siempre es una instancia de clase sí el tipo de la excepción es un objeto de clase); traza recibe un objeto traza (consultar el Manual de referencia) que encapsula la pila de llamadas en el punto en que ocurrió la excepción originalmente.(Atención: asignar el valor que se regresa (traceback) a una variable local en una función que está manejando una excepción puede una referencia circular). Dado que la mayoría de las funciones no necesitan el acceso al traceback, la mejor solución es algo como esto:

type, value = sys.exc-info()[:2]

Si necesita el traceback, asegúrese de borrar el mismo después de usarlo (lo mejor es hacerlos con un try ... en la sentencia final). O llamar al módulo exec-info() en una función que no maneje excepciones.

exc-type

exc-value

exc-traceback

Debido a que hay variable globales, no estan especificadas en el hilo actual, así que su uso no es seguro en un programa multi-hilos. Cuando una excepción no está siendo manejada, exec-type es puesto en None y los otros dos están indefinidos.

exec-prefix

Una cadena el sitio-específico del prefijo del directorio, donde los archivos Python, de la dependencia de plataforma (platform-dependent) son instalados; por default es ‘/usr/local’. Este puede ser hecho a tiempo de ejecución con el argumento exec-prefix para configurar el script. Específicamente, todos los archivos de configuración (e.g. los archivos de cabecera c0nfig.h) son instalados en el directorio exec-prefix + ‘/lib/pythonversion/config’ y los m6dulos de las librerías compartidas son instalados en in exec-prefix + ‘/lib/pythonversion/lib-dynload’, donde version es igual a version[:3].

executable

Una cadena da el nombre de el ejecutable binario para el interprete de Python, en sistemas donde esto tiene sentido.

exit([arg])

Sale de Python. Es implementado por el levantamiento de la excepción SystemExit. El argumento opcional arg puede ser un entero que determina el estado de la salida (por default O), u otro tipo de objeto. Si es un entero O es considerado como “terminación exitosa” (successfull termination) y cualquier otro valor es considerado como “terminación abnormal” (abniormal termination). Muchos sistemas requieren que esté definido en un rango 0-127, de otra forma produce resultados inesperados. Algunos sistemas tienen una convención para asignar significado a un específico código de salida, pero estos por lo general son subdesarrollados; los programas de Unix usan 2 para errores de sintaxis en la línea de comandos y 1 para cualquier otro tipo de errores. Si cualquier otro tipo de objeto es pasado, none, es equivalente a pasar cero, y cualquier otro objeto es impreso en sys.stderr y el resultado en un código de salida de 1. En particular, sys.exit(“algunos mensajes de error”) es una forma rápida de salir del programa cuando ocurre un error.

exiffunc

Este valor no es definido actualmente por el módulo, pero puede ser definido por el usuario, para especificar las acciones de limpieza al salir del programa. Cuando se especifica, puede ser una función parametrizada. Esta función puede ser llamada cuando se salga éI interprete. Solo una función puede ser instalada en esta forma; para permitir que múltiples funciones puedan ser llamada al salir, use el módulo atexit. Nota: las funciones de salida no

son llamadas cuando el programa es “matado” (abortado), cuando se da un error interno fatal 6 cuando os.exit() es llamado. getrefcount(objet0)

Regresa la cuenta de referencia del objeto. La cuenta regresada es por lo general más grande de lo que se espera, por ello se incluye la referencia (temporal) con un argumento de getrefcount().

getrecursionlimit ()

Regresa el valor actual del limite de recursión, el tamaño máximo del interprete de stack de Python. Este límite previene una recursión infinita que pueda causar un overflow en el stack por parte de los módulos de C y con ello tira (crashing). Esto puede ser hecho por setrecursionlimit().

hexversion

El número de versión decodificado como un entero. Está es una garantía para mejorar cada una de las versiones, incluyendo el soporte apropiado. Por ejemplo, para probar que el interprete es de la Mima versión de Python, usamos:

if sys.hexversion >= OxO10502FO: # use some advanced feature

else: ...

# use an alternative implementation or warn the user ...

last-type

last-value

last-traceback

Estas tres variables no siempre están definidas; son puestas cuando una excepción no es manejada y el interprete imprime un mensaje de error y un tracebak en el stack. El significado de las variables es el mismo como el valor que es regresado por exec-info() hacia delante. (Dado que solo hay un hilo interactivo, el hilo-seguridad no le concierne a estas variables, a menos claro exec-type etc).

maxint

El máximo entero soportado por el tipo regular entero de Pytho. Este es por lo menos 2**31-1. El máximo entero negativo es -maxint-1 - el resultado asimétrico del uso de la aritmética de complemento binario.

modules

Este es un diccionario que muestra los nombres de los módulos que hayan sido cargados. Estos pueden ser manipulados para forzar la recarga de los módulos y otros trucos.

Note que el remover un módulo de este directorio no es lo mismo que llamar al módulo reload() en el objeto correspondiente de cada módulo.

path

Una lista de cadenas que especifica la ruta de búsqueda para los módulos. lnicializada por la variable de ambiente $PYTHONPATH, o una dependencia de inicialización por default. El primer elemento de esta lista, path[O], es el directorio que contiene el script que fue usado para invocar el intérprete de Python. Si el directorio del script no está disponible (e.g. si el interprete es invocado indirectamente ó si el script es leído desde una entrada estándar), path[O] es una cadena vacía, la cual direccióna a Python para buscar los módulos en el actual directorio primero. Note que el directorio script es insertado antes de los enteros insertados como resultado de $PYTHONPATH

plataform

Esta cadena contiene el identificador de la plataforma, e.g. ‘sunos5’ or ‘linuxl’. Este puede ser usado para agregar componentes específicos de la plataforma al path, por mencionar uno.

prefijo

Cadena que da el prefijo del directorio del sitio específico donde los archivos de Python que son independientes de la plataforma, son instalados; por default, es la cadena ‘/usr/local’. Este puede ser activado al tiempo de construcción con el argumento -- prefix para el script de configuración. La principal colección de las módulos de librerías de Python esta es el instalado en el directorio prefix + ‘/lib/pythonversion’ mientras que las cabeceras de los archivos independientes de la plataforma (todo excepto c0nfig.h) son almacenado en prefix + ‘/include/pythonversion’, donde versión es igual a versión[:3].

Especifican el prompt primero y secundario del intérprete. Están definidos solo si el intérprete está en un modo interactivo. Los valores iniciales son ‘‘>>>’ y ‘... ‘. Si un objeto que no es string es asignado a una de estas dos variables, str() es revaluado cada vez que el interprete se prepara para leer un nuevo comando; Este puede ser usado para implementar un prompt dinámico.

setcheckinterval (interval)

Activa el “el intervalo de validación” del intérprete. El valor del entero determina que tan seguido el intérprete valida las cosas periódicas tales como switchs de hilos y manejadores de señales. El valor por default es 10, Significa que la validación es realizada cada 10 instrucciones virtuales de Python. Poner un valor más grande puede incrementar el performance para programas que usan hilos. Poner un valor <= O valida cada instrucción virutal, aumentando al máximo la sensibilidad del interprete.

setprofile (profilefunc)

Activa la función del perfil del sistema, la cual le permite implementar el c6digo fuente para un perfil en Python. La función de perfil del sistema es llamado de forma similar a la función de sistema settrace() (función de rastreo), pero no es llamada para cada línea de código ejecutada (solo en la llamada, en el regreso de datos y cuando ocurre una excepción). setrecursionlimit (limit)

Pone el valor máximo para el stack del interprete de Python al valor limit. Este valor (limit) previene recursiones infinitas lo cual puede causar un overflow del stack de C y con ello “tirar” (crashing) Python. El valor máximo depende de la plataforma que se esté usando. Un usuario puede necesitar poner el valor máximo cuando tenga un programa que requiera una recursión profunda y una plataforma que soporte el m&ximo valor. Esto deberfa ser hecho con mucho cuidado, debido a que a que el valor limite puede romper el sistema.

settrace (tracefunc)

Activa la función del sistema trace, la cual te permite implementar un depurador de código fuente en Python.

stdin

stdout

stderr

Objetos de archivos que corresponden a la entrada estándar del intérprete, salida y cadenas de errores. stdin es usada para todas las entradas del intérprete excepto para los scripts que incluyan llamadas a las funciones input() y raw-input(). stdout es usado para la salida a impresión (en pantalla), para declaración de expresiones y para las salidas a pantalla para las funciones input() y raw-input(). El prompt del intérprete y (al menos la mayoría) de los mensajes de error se escriben en stderrstdout y stderr no necesita ser construido en el archivo de objetos: cualquier objeto es permitido siempre y cuando tenga un método write() que tome la cadena de argument (al cambiar estos objetos no se afecta las cadenas estándar de I/O, del proceso ejecutado por os.popen(), os.system() or exec(), las cuales son parte de las funciones del módulo os.)

Estos objetos contienen los valores originales de stdin, stderr y stdout al inicio del programa. Son utilizados durante la finalización, y pueden ser usados para restaurar los archivos originales si han sido corrompidos.

tracebacklimit

Cuando este valor es activado a un valor entero, determina el número máximo de niveles información de traceback impreso cuando ocurre una excepción no manejada. El valor

por default es 1000. Cuando su valor es O o menor, toda la información referente al traceback es suprimida y solo los tipos de excepciones y valores son impresos.

version

Una cadena contiene la versión del intérprete de Python, además de información adicional sobre el tipo de cornpilador. Su valor es de la forma ‘version (#build-nombre, build-date, build-time) [compile]’. Los primeros tres caracteres son usados para identificar la versión en los directorios de instalación. Por ejemplo:

>>> import sys >>> sys.version ‘1 5 . 2 (#O Apr 13 1999, 10:51: 12) [MSC 32 bit (Intel)]’

version-info

Es la tupla que contiene los cinco componentes del número de versión: mayor, menor, micro, liberación y serial. Todos los valores son enteros excepto el de libración cuyos valores con ‘alpha’, ‘beta’, ‘candidate’ o ‘final’. Los valores de versión-info para la versión 2.0 de Python son (2,0,0,’finalJ,0).

winver

Es el número de versión usado para registrar las claves en la plataforma de Windows. Este es almacenado como una cadena en el DLL de Python. Los valores normalmente son los primeros tres caracteres de la versión. Este se obtiene del módulo sys, para propósitos de información; modificar estos valores no afecta las claves usadas por Python.

16.2 gc -- lnterfaz recolectora de basura

El módulo gc solo está disponible si el interprete fue construido con el detector de basura cíclico (habilitado por default). SI no estaba habilitado, un ImportError es generado. Este módulo provee una interfaz para el recolector opcional de basura. Provee la posibilidad de deshabilitar el recolector, poner la frecuencia de recolección, y poner las opciones de depuración (debugging). Debido a que los suplementos de recolección son usados en Python, se puede deshabilitar el recolector si está seguro que su programa no crea ciclos de referencia. El módulo gc provee las siguientes funciones:

enable ()

Habilita automáticamente el recolector de basura.

disable()

Deshabilita automáticamente el recolector de basura.

isenabledo

Regresa verdadero sí una recolección automática esta habilitada

collect()

Ejecuta una recolección. Todas las generaciones son examinadas y regresa el número de objetos no recuperados.

set-degub(flag)

Activa las banderas del depurador del recolector de basura. La información del depurador puede ser escrita a sysstderr. Más adelantes se muestran las banderas del depurador las cuales pueden ser combinadas usando las operaciones de bits, esto para controlar la depuración.

Regresa las banderas de depuración que están activas.

Activa los parámetros de la frecuencia de recolección. Poniendo threshold en cero deshabilita la recolección. El módulo GC clasifica los objetos en tres tipos, dependiendo de cuanto “barra”. Los objetos nuevos son puestos en la más reciente generación. Si un objeto sobrevive a la primer recolección es movido al siguiente nivel más viejo. Dado que el nivel 2 es el más viejo, los objetos permanecen ahí hasta que se haga una recolección.

get-threshold()

Regresa et valor actual de recolección como una tupla (thresholdo, thresholdl, threshold2)

16.3 atexit -- Gestores de salida

New in version 2.0. El módulo atexit define una sencilla función para el registro de funciones de limpieza. Las funciones así registradas son automáticamente ejecutadas tras una finalización normal del intérprete. Nota: las funciones registradas a través de este módulo no se llaman cuando se mata el programa por una señal, cuando se detecta un error fatal interno de Python, o cuando se llama a la función os.-exit(). Esta es una interfaz alternativa a las funciones proporcionadas por la variable sys.exitfunc. Nota: es poco probable que este módulo funcione correctamente si en el código se emplea sys.exitfunc. Es posible que otros módulos del núcleo de Python usen atexit sin que el programador lo sepa. Quienes empleen sys.exitfunc deben cambiar a atexit. La manera más simple de realizar este cambio es importar el módulo atexit y registrar la función enlazada a sys.exitfunc.

register (func[, *args[, **kargs]])

Registra func como la función que se ejecutará al término del programa. Los argumentos opcionales pasados a func también han de ser pasados a la función register(). Con la terminación normal del programa (por ejemplo, si se llama a la función sys.exit() o termina la ejecución del módulo principal) todas las funciones registradas se llaman, empezando por la irltima y terminando por la primera. Se asume que los módulos de nivel más bajo se importan antes que aquellos de nivel más alto, de ahí que sean limpiados más tarde.

16.3.1 Ejemplo de atexit

El siguiente ejemplo muestra cómo un módulo puede iniciar un contador desde un fichero cuando se importa, y guardar automáticamente el valor actualizado del contador cuando el programa termina sin necesidad de que la aplicación haga una llamada explícita a este módulo durante la finalización.

count = int(open("/tmp/counter").read()) except IOError: - count = O

def incrcounter(n): global -count - count = "count + n

def savecounter(): open("/tmp/counter", "w").write("%d" % -count)

import atexit atexit.register(savecounter)

16.4 Types - Nombre para todos los tipos built-in

Este módulo define los nombres para todos los tipos de objetos que son usados por el intérprete estándar de Python, pero no para los tipos definidos por otros módulos. Es seguro usar la sentencia “from types import” debido a que el módulo no exporta ningún nombre que no se encuentre e está lista. Nuevos nombres son exportados para versiones futuras de este módulo terminaran en “Type”. Típicamente esto es usado por funciones que hacen diferentes cosas dependiendo del tipo de argumentos, como sigue:

from types import * def delete(list, item):

del list[item]

list.remove(item)

if type(item) is IntType:

else:

El módulo define los siguientes nombres:

NoneType

El tipo de None

El tipo del tipo de objetos

IntType

El tipo de enteros (e.g. 1).

LongType

El tipo de enteros largos (e.g. IL).

FloatType

El tipo de números de punto flotante (e.g. 1 .O).

ComplexType

El tipo de número complejo (e.g. 1 .Oj).

StringType

El tipo de cadenas de caracteres (e.g.’Spam’).

UnicodeType

El tipo de cadenas de caracteres Unicode (e.g. u’spam’).

TupleType

Tipo de tuplas (e.g. (1,2,3,’Spam’)).

ListType

Lista de tipos (e.g. [0,1,2,3])

DicType

Tipo de directorios (e.g. {‘Bacon’: 1, ‘Ham’ : O})

DictionaryType

Un nombre alterno para DicType

FunctionType

Tipo de funciones definidas por el usuario

CodeType

Tipo de objetos código que regresa el compilador

ClassType

Tipo de clases definidas por el usuario.

InstanceType

Tipo de instancias de las clases definidas por el usuario.

MethodType

Tipo de métodos de las instancias de las clases definidas por el usuario.

UnboundMethodType

Un nombre alterno para MethodType

BuiltinFunctionType

Tipo de funciones de construcción como len() o sys.exit()

BuiltinMethodType

Un nombre alterno para BuiltinFunctionType

ModuleType

Tipo de módulos

16.5 UserDict - Empacador de Clases para objetos diccionario

Este módulo define las clases que actúan como un empacador de objetos diccionario. Es una clase base utilizada para su propio diccionario de clases, las cuales pueden heredar de ellas ó pueden sobrescribir métodos existentes 6 agregar otros. De esta forma se pueden agregar nuevas características al diccionario. El módulo UserDict define la clase UserDict:

UserDict([initialdata])

Clase que simula un diccionario. El contenido de las instancias en mantenido en un diccionario común, al cual se puede acceder por medio de los atributos de la instancia UserDict, Si initialdata es proporcionado, la “data” es inicializado con el contenido del mismo.

data

Diccionario real que se utiliza para almacenar el contenido de la clase UserDlct

16.6 UserList -- Empacador de Clases para objetos String

Este módulo define una clase que actual como un empacador de objetos lista. Es una clase base utilizada para su propia lista de clases, las cuales pueden ser heredadas y sobrescribir métodos ya existentes 6 agregar nuevo. De esta manera se pueden agregar nuevas características a la lista. Se puede ver que estas clases son demasiado ineficientes comparado con el objeto Lista.

UserString([/isf])

Clase que simula un objeto lista. El contenido de las instancias es mantenido en un objeto lista, a la cual se puede acceder por medio de los atributos de la instancia de Userstring. El contenido de las instancias inicialmente es inicializadas con una copia del parámetro list. list puede contener una lista de Python.

data

Una objeto lista de Python, usados para almacenar el contenido de la clase Userlist.

16.7 Userstring -- Empacador de Clases para objetos String

Este módulo define una clase que actual como un empacador de objetos lista. Es una clase base utilizada para su propia lista de clases, las cuales pueden ser heredadas y sobrescribir métodos ya existentes ó agregar nuevo. De esta manera se pueden agregar nuevas características a la lista. Se puede ver que estas clases son demasiado ineficientes comparado con los objetos Unicode ó string.

UserString([sequenceI)

Clase que simula un objeto string 6 Unicode. El contenido de las instancias es mantenido en un objeto string ó Unicode, a la cual se puede acceder por medio de los atributos de la instancia de Userstring. El contenido de las instancias inicialmente es inicializadas con una copia del parámetro sequence. sequence puede contener una cadena regula de Python ó una cadena Unicode, una instancia de Userstring ó una secuencia arbitraria la cual puede ser convertida en una cadena usando la función str().

MutableString([sequence])

Esta clase es derivada de la clase Userstring, redefine las cadenas para ser mutantes. Las cadenas mutantes pueden ser usadas como llaves de un diccionario, ya que los diccionarios necesitan un objeto no mutante como llave. La principal intención de esta clase es servir como un ejemplo educativo para la herencia y la necesidad de remover (sobrescribir) el método "hash-.

data

Una objeto string 6 Unicode de Python, usados para almacenar el contenido de la clase Userstring.

16.8 operator -- Operaciones estándar como funciones

Este módulo exporta un conjunto de funciones implementadas en C, corresponden a operadores intrínsecos de Python. Por ejemplo, operator.add(x,y) es equivalente a la expresión x + y. Los nombres de las funciones son los mismos que los usados para métodos de clases especiales. El módulo operator define las siguientes funciones.

Regresa a + b, para los número a y b

Regresa a - b.

Regresa a * b, para los número a y b.

div (a, b ) - div- (a, b )

Regresa a I b

Regresa a % b.

Regresa o negado.

Regresa o positivo.

abs (o) - abs- (0)

Regresa el valor absoluto de o.

inv (o ) - inv- (o) - invert- (o)

Regresa el inverso de o.

lshift (a, b) - Ishift- (a, b)

Regresa a movido a la izquierda b posiciones.

rshift (a, b) - rshift- (a, b )

Regresa a movido a la derecha b posiciones.

Regresa el resultado de la operación lógica a AND b

Regresa el resultado del a operación lógica a OR b.

Regresa el resultado del a operación lógica a XOR b.

Regresa el resultado de la operación lógica NOT (negación)

truth (o)

Regresa 1 si o es verdadero, O en otro caso.

concat (a, b) - concat- (a, 6)

Regresa la concatenación de las variables a y b

repeat (a, b) - repeat- (a, b)

Repite a tantas veces como b, a es una secuencia

countof (a, b)

Regresa el número de ocurrencias de b en a.

indexof (a, b)

Regresa el índice de la primera ocurrencia de b en a.

getitem (a, b) - getitem- (a, b )

Regresa el valor de a cuyo indices es b.

setitem (a, b, c) - setitem- (a, b, c)

Pone el valor de a con índice b en c.

delitem (a, b) - delitem- (a, b)

Remueve el valor de con índice b

getslice (a, b, c) - getslice- (a, b, c)

Regresa el conjunto de registro de a desde el índice b hasta el índice c - 1

setslice (a, b, c, v) - setslice- (a, b, c, v)

Pone el conjunto de registros de a desde el índice b hasta el índice c - 1 a una secuencia v..

delslice (a, b, c) - delslice- (a, b, c)

Borra el conjunto de registros de a desde el índice b hasta c - 1

Bibliografía

Guía de aprendizaje de Python Guido van Rossum Corporation for National Research Initiatives (CNRI) 1895 Preston White Drive, Reston, Va 20191, USA

0 Python instantáneo por Magnus Lie Hetland

0 Python Language Mapping Version 1.1 Martin Chilvers Bill Janssen Martin von Lowis

The What, Why, Who, and Where of Python Learn about Python, the language that wraps itself around a problem to squeeze out a solution, swallowing it whole. By Aaron R. Watters [Editor’s Notes: 17 Nov 96. Update articl e with information on a book from O’Reilly and Associates]

0 Aprendiendo a programar por Alan Gauld Traducción de Martin Pozzi

Non-Programmers Tutorial For Python Josh Cogliati Copyright(c) 1999-2000 Josh Cogliati.

Referencia de la Biblioteca de Python Guido van Rossum Fred L. Drake, Jr., editor BeOpen PythonLabs

An introduction to Tkinter By Fredrik Lundh


Recommended