Python Tutorial r66
Python Tutorial r66
Ingeniería en Computación
2021
Tutorial de Python
El oficial con ajustes
Nota del recopilador, ¡este no es el tutorial completo! Dejo afuera momentáneamente algunas
cosas para mantener bajo control el tamaño del apunte. Así como que hay algunas secciones
traducidas que no están presentes en el tutorial oficial. No es exactamente igual.
Las referencias cruzadas en su mayoría no funcionan, aunque el documento apunta mucho a la
documentación oficial del lenguaje.
Tomado casi todo de https://docs.python.org/es/3.7/tutorial/index.html
Python es un lenguaje de programación potente y fácil de aprender. Tiene estructuras de datos
de alto nivel eficientes y un simple pero efectivo sistema de programación orientado a objetos.
La elegante sintaxis de Python y su tipado dinámico, junto a su naturaleza interpretada lo
convierten en un lenguaje ideal para scripting y desarrollo rápido de aplicaciones en muchas
áreas, para la mayoría de plataformas.
El intérprete de Python y la extensiva librería estándar se encuentran disponibles libremente en
código fuente y forma binaria para la mayoría de plataformas desde la Web de Python,
https://www.python.org/, y se pueden distribuir libremente. El mismo sitio contiene
distribuciones y direcciones a muchos módulos de Python de terceras partes, programas,
herramientas y adicionalmente documentación.
Este tutorial no pretende ser exhaustivo y cubrir todas las funcionalidades, o siquiera las más
utilizadas. Solo pretende introducirlos a muchas de las funcionalidades más notables y dar una
idea del estilo y el tipo de lenguaje. Al completarlo, podrás leer y escribir módulos y programas
en Python y estarás listo para aprender sobre varias librerías y módulos descritos en The Python
Standard Library.
r66/2021(MrTín) Página 1 de 82
Introducción a la
Ingeniería en Computación
2021
Abriendo el apetito
Si trabajas mucho con ordenadores, en algún momento encontrarás que hay alguna tarea que
quieres automatizar. Por ejemplo, quizás quieres buscar y remplazar un texto en muchos
ficheros o renombrar y reordenar un montón de imágenes de forma complicada. Quizás lo que
quieres es escribir una pequeña base de datos personalizada, una interfaz gráfica o un juego
simple.
Si eres un desarrollador profesional, quizás quieres trabajar con varias librerías de C/C++/Java
pero encuentras el ciclo de escribir/compilar/probar/recompilar bastante lento. Quizás estás
escribiendo una serie de pruebas para éstas librerías y te parece tedioso escribir el código de
pruebas. O quizás has escrito un programa que puede utilizar un lenguaje como extensión y no
quieres diseñar e implementar un lenguaje entero para tu aplicación.
Python es justo el lenguaje para ti.
Podrías escribir un shell script de Unix o un fichero batch de Windows para alguna de estas
tareas pero los shell scripts son mejores para mover ficheros y cambiar texto no para
aplicaciones con interfaz gráfica o juegos. Podrías escribir un programa en C/C++/Java pero
puede llevar mucho tiempo de desarrollo incluso para tener el primer borrador. Python es más
simple de utilizar, disponible en los sistemas operativos Windows, Mac OS X y Unix y te ayudará
a realizar el trabajo de forma más rápida.
Python es fácil de utilizar siendo un lenguaje de programación real ofreciendo mucha más
estructura y soporte para programas grandes que la que ofrecen shell scripts o ficheros batch.
Por otro lado, Python también ofrece mayor comprobación de errores que C y siendo un
lenguaje de muy alto nivel tiene tipos de datos de alto nivel incorporados como listas flexibles y
diccionarios. Debido a sus tipos de datos más generales, Python es aplicable a más dominios
que Awk o Perl, aunque hay muchas cosas que son tan sencillas en Python como en esos
lenguajes.
Python te permite dividir tu programa en módulos que pueden reutilizarse en otros programas
de Python. Tiene una gran colección de módulos estándar que puedes utilizar como la base de
tus programas o como ejemplos para empezar a aprender Python. Algunos de estos módulos
r66/2021(MrTín) Página 2 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 3 de 82
Introducción a la
Ingeniería en Computación
2021
El resto del tutorial introduce varias características del lenguaje y el sistema Python a través de
ejemplos, empezando con expresiones, instrucciones y tipos de datos simples, pasando por
funciones y módulos, y finalmente tocando conceptos avanzados como excepciones y clases
definidas por el usuario.
r66/2021(MrTín) Página 4 de 82
Introducción a la
Ingeniería en Computación
2021
Números
El intérprete puede utilizarse como una simple calculadora; puedes introducir una expresión y
este escribirá los valores. La sintaxis es sencilla: los operadores +, -, * y /``funcionan
como en la mayoría de los lenguajes (por ejemplo, Pascal o
C); los paréntesis (``()) pueden ser usados para agrupar. Por ejemplo:
>>> 2 + 2
r66/2021(MrTín) Página 5 de 82
Introducción a la
Ingeniería en Computación
2021
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating point number
1.6
Los números enteros (ej. 2, 4, 20) tienen tipo int, los que tienen una parte fraccionaria (por
ejemplo 5.0, 1.6) tiene el tipo float. Vamos a ver más acerca de los tipos numéricos más
adelante en el tutorial.
La división (/) siempre devuelve un punto flotante. Para hacer floor division y obtener un
resultado entero (descartando cualquier resultado fraccionario) puede usarse el operador //;
para calcular el resto puedes usar %:
>>> 5 ** 2 # 5 squared
25
>>> 2 ** 7 # 2 to the power of 7
128
Debido a que ** tiene una prioridad mayor que `-, -3**2 se interpretará como
-(3**2), por lo tanto dará como resultado -9. Para evitar esto y obtener 9,
puedes usar (-3)**2.
El signo igual (=) se usa para asignar un valor a una variable. Ningún resultado se mostrará
antes del siguiente prompt interactivo:
>>> width = 20
r66/2021(MrTín) Página 6 de 82
Introducción a la
Ingeniería en Computación
2021
>>> height = 5 * 9
>>> width * height
900
Si una variable no está «definida» (no se le ha asignado un valor), al intentar usarla dará un
error:
Hay soporte completo de punto flotante; operadores con operando mezclados convertirán los
enteros a punto flotante:
>>> 4 * 3.75 - 1
14.0
En el modo interactivo, la última expresión impresa se asigna a la variable _. Esto significa que
cuando se está utilizando Python como calculadora, es más fácil seguir calculando, por ejemplo:
Esta variable debe ser tratada como de sólo lectura por el usuario. No le asignes explícitamente
un valor; crearás una variable local independiente con el mismo nombre enmascarando la
variable con el comportamiento mágico.
Además de int y float, Python admite otros tipos de números, como Decimal y
Fraction. Python también tiene soporte incorporado para complex numbers, y usa el sufijo j
o J para indicar la parte imaginaria (por ejemplo, 3+5j).
r66/2021(MrTín) Página 7 de 82
Introducción a la
Ingeniería en Computación
2021
Cadenas de caracteres
Además de números, Python puede manipular cadenas de texto, las cuales pueden ser
expresadas de distintas formas. Pueden estar encerradas en comillas simples ('...') o
dobles ("...") con el mismo resultado. \ puede ser usado para escapar comillas:
r66/2021(MrTín) Página 8 de 82
Introducción a la
Ingeniería en Computación
2021
Second line.
Si no quieres que los caracteres precedidos por \ se interpreten como caracteres especiales,
puedes usar cadenas sin formato agregando una r antes de la primera comilla:
Las cadenas de texto literales pueden contener múltiples líneas. Una forma es usar triples
comillas: """...""" o '''...'''. Los fin de línea son incluidos automáticamente, pero
es posible prevenir esto agregando una \ al final de la línea. Por ejemplo:
print("""\
Uso: programita [OPTIONS]
-h Muestra este mensaje de ayuda
-H hostname Hostname al cual conectarse
""")
produce la siguiente salida (tened en cuenta que la línea inicial no está incluida):
Las cadenas se pueden concatenar (pegar juntas) con el operador + y se pueden repetir con *:
Dos o más cadenas literales (es decir, las encerradas entre comillas) una al lado de la otra se
concatenan automáticamente.
r66/2021(MrTín) Página 9 de 82
Introducción a la
Ingeniería en Computación
2021
Las cadenas de texto se pueden indexar (subíndices), el primer carácter de la cadena tiene el
índice 0. No hay un tipo de dato diferente para los caracteres; un carácter es simplemente una
cadena de longitud uno:
Los índices quizás sean números negativos, para empezar a contar desde la derecha:
Nota que -0 es lo mismo que 0, los índice negativos comienzan desde -1.
r66/2021(MrTín) Página 10 de 82
Introducción a la
Ingeniería en Computación
2021
Además de los índices, las rebanadas también están soportadas. Mientras que los índices se
utilizar para obtener caracteres individuales, las rebanadas te permiten obtener partes de las
cadenas de texto:
Nota cómo el inicio siempre se incluye y el final siempre se excluye. Esto asegura que s[:i]
+ s[i:] siempre sea igual a s:
Los índices de las rebanadas tienen valores por defecto útiles; el valor por defecto para el
primer índice es cero, el valor por defecto para el segundo índice es la longitud de la cadena a
rebanar.
Una forma de recordar cómo funcionan las rebanadas es pensar que los índices apuntan entre
caracteres, con el borde izquierdo del primer carácter numerado 0. Luego, el punto derecho del
último carácter de una cadena de n caracteres tiene un índice n, por ejemplo
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
La primera fila de números da la posición de los índices 0…6 en la cadena; La segunda fila da los
correspondientes indices negativos. La rebanada desde i hasta j consta de todos los caracteres
entre los bordes etiquetados i y j, respectivamente.
r66/2021(MrTín) Página 11 de 82
Introducción a la
Ingeniería en Computación
2021
Sin embargo, los índices de rebanadas fuera de rango se manejan satisfactoriamente cuando se
usan para rebanar:
>>> word[4:42]
'on'
>>> word[42:]
''
Las cadenas de Python no se pueden modificar, son immutable. Por eso, asignar a una posición
indexada de la cadena resulta en un error:
>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34
Ver también
r66/2021(MrTín) Página 12 de 82
Introducción a la
Ingeniería en Computación
2021
Las cadenas de texto son ejemplos de tipos secuencias y soportan las operaciones
comunes para esos tipos.
String Methods
Las cadenas de texto soportan una gran cantidad de métodos para transformaciones
básicas y búsqueda.
Formatted string literals
Aquí se describen con más detalle las antiguas operaciones para formateo utilizadas
cuando una cadena de texto está a la izquierda del operador %.
Listas
Python tiene varios tipos de datos compuestos, utilizados para agrupar otros valores. El más
versátil es la lista, la cual puede ser escrita como una lista de valores separados por coma
(ítems) entre corchetes. Las listas pueden contener ítems de diferentes tipos, pero usualmente
los ítems son del mismo tipo.
Al igual que las cadenas (y todas las demás tipos integrados sequence), las listas se pueden
indexar y segmentar:
r66/2021(MrTín) Página 13 de 82
Introducción a la
Ingeniería en Computación
2021
Todas las operaciones de rebanado devuelven una nueva lista que contiene los elementos
pedidos. Esto significa que la siguiente rebanada devuelve una copia nueva (superficial) de la
lista:
>>> squares[:]
[1, 4, 9, 16, 25]
A diferencia de las cadenas, que son immutable, las listas son de tipo mutable, es decir, es
posible cambiar su contenido:
También puede agregar nuevos elementos al final de la lista, utilizando el método append()
(vamos a ver más sobre los métodos luego):
También es posible asignar a una rebanada, y esto incluso puede cambiar la longitud de la lista
o vaciarla totalmente:
r66/2021(MrTín) Página 14 de 82
Introducción a la
Ingeniería en Computación
2021
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]
Es posible anidar listas (crear listas que contengan otras listas), por ejemplo:
r66/2021(MrTín) Página 15 de 82
Introducción a la
Ingeniería en Computación
2021
>>> i = 256*256
>>> print('El valor de i es', i)
El valor de i es is 65536
r66/2021(MrTín) Página 16 de 82
Introducción a la
Ingeniería en Computación
2021
El parámetro nombrado end puede usarse para evitar el salto de linea al final de la salida,
o terminar la salida con una cadena diferente:
>>> a, b = 0, 1
>>> while a < 1000:
... print(a, end=',')
... a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
r66/2021(MrTín) Página 17 de 82
Introducción a la
Ingeniería en Computación
2021
Ademas de la instrucción while que introdujimos recientemente, Python usa las sentencias de
control conocidas de otros lenguajes de programación pero con algunos giros.
La sentencia if
Tal vez el tipo más conocido de sentencia sea el if. Por ejemplo:
Puede haber cero o más bloques elif, y el bloque else es opcional. La palabra reservada
“elif’es una abreviación de “else if”, y es útil para evitar un sangrado excesivo. Una secuencia
if … elif … elif … sustituye las sentencias switch o case encontradas en otros
lenguajes.
La sentencia for
La sentencia for en Python difiere un poco de lo que uno puede estar acostumbrado en
lenguajes como C o Pascal. En lugar de siempre iterar sobre una progresión aritmética de
números (como en Pascal) o darle al usuario la posibilidad de definir tanto el paso de la iteración
como la condición de fin (como en C), la sentencia for de Python itera sobre los ítems de
cualquier secuencia (una lista o una cadena de texto), en el orden que aparecen en la secuencia.
Por ejemplo:
r66/2021(MrTín) Página 18 de 82
Introducción a la
Ingeniería en Computación
2021
Si necesitas modificar la secuencia sobre la que estás iterando mientras estás adentro del ciclo
(por ejemplo para borrar algunos ítems), se recomienda que hagas primero una copia. Iterar
sobre una secuencia no hace implícitamente una copia. La notación de rebanada es
especialmente conveniente para esto:
>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
Con for w in words:, el ejemplo intentaría crear una lista infinita, insertando
defenestrate una y otra vez.
La función range()
Si se necesita iterar sobre una secuencia de números, es apropiado utilizar la función integrada
range(), la cual genera progresiones aritméticas:
El valor final dado nunca es parte de la secuencia; range(10) genera 10 valores, los índices
correspondientes para los ítems de una secuencia de longitud 10. Es posible hacer que el rango
empiece con otro número, o especificar un incremento diferente (incluso negativo; algunas
veces se lo llama “paso”):
r66/2021(MrTín) Página 19 de 82
Introducción a la
Ingeniería en Computación
2021
range(5, 10)
5, 6, 7, 8, 9
range(0, 10, 3)
0, 3, 6, 9
Para iterar sobre los índices de una secuencia, puedes combinar range() y len() así:
En la mayoría de los casos, sin embargo, conviene usar la función enumerate(), mira
Técnicas de iteración.
Algo extraño sucede si muestras un ` range`:
>>> print(range(10))
range(0, 10)
De muchas maneras el objeto devuelto por range() se comporta como si fuera una lista, pero
no lo es. Es un objeto que devuelve los ítems sucesivos de la secuencia deseada cuando iteras
sobre él, pero realmente no construye la lista, ahorrando entonces espacio.
Decimos que tal objeto es iterable; esto es, que se lo puede usar en funciones y construcciones
que esperan algo de lo cual obtener ítems sucesivos hasta que se termine. Hemos visto que la
declaración for es un iterador en ese sentido. La función list() es otra; crea listas a partir
de iterables:
>>> list(range(5))
[0, 1, 2, 3, 4]
Más tarde veremos más funciones que devuelven iterables y que toman iterables como entrada.
r66/2021(MrTín) Página 20 de 82
Introducción a la
Ingeniería en Computación
2021
Las sentencias de bucle pueden tener una cláusula`!else` que es ejecutada cuando el lazo
termina, luego de agotar la lista (con for) o cuando la condición se hace falsa (con while),
pero no cuando el bucle se termina con la sentencia break. Se puede ver el ejemplo en el
siguiente bucle, que busca números primos:
(Sí, este es el código correcto. Fíjate bien: el else pertenece al ciclo for, no al if.)
Cuando se usa con un ciclo, el else tiene más en común con el else de una declaración try
que con el de un if: el else de un try se ejecuta cuando no se genera ninguna excepción, y
el else de un ciclo se ejecuta cuando no hay ningún break. Para más sobre la declaración
try y excepciones, mira Gestionando Excepciones.
La declaración continue, también tomada de C, continua con la siguiente iteración del ciclo:
r66/2021(MrTín) Página 21 de 82
Introducción a la
Ingeniería en Computación
2021
La sentencia pass
La sentencia pass no hace nada. Se puede usar cuando una sentencia es requerida por la
sintaxis pero el programa no requiere ninguna acción. Por ejemplo:
Otro lugar donde se puede usar pass es como una marca de lugar para una función o un
cuerpo condicional cuando estás trabajando en código nuevo, lo cual te permite pensar a un
nivel de abstracción mayor. El pass se ignora silenciosamente:
Definiendo funciones
Podemos crear una función que escriba la serie de Fibonacci hasta un límite determinado:
r66/2021(MrTín) Página 22 de 82
Introducción a la
Ingeniería en Computación
2021
La palabra reservada def se usa para definir funciones. Debe seguirle el nombre de la función y
la lista de parámetros formales entre paréntesis. Las sentencias que forman el cuerpo de la
función empiezan en la línea siguiente, y deben estar con sangría.
La primera sentencia del cuerpo de la función puede ser opcionalmente una cadena de texto
literal; esta es la cadena de texto de documentación de la función, o docstring. (Puedes
encontrar más acerca de docstrings en la sección Cadenas de texto de documentación.).
Existen herramientas que usan las docstrings para producir documentación imprimible o
disponible en línea, o para dejar que los usuarios busquen interactivamente a través del código;
es una buena práctica incluir docstrings en el código que escribes, y hacerlo un buen
hábito.
La ejecución de una función introduce una nueva tabla de símbolos utilizada para las variables
locales de la función. Más precisamente, todas las asignaciones de variables en una función
almacenan el valor en la tabla de símbolos local; mientras que las referencias de variables
primero buscan en la tabla de símbolos local, luego en las tablas de símbolos locales de las
funciones adjuntas, luego en la tabla de símbolos global y finalmente en la tabla de nombres
incorporados. Por lo tanto, a las variables globales y a las variables de funciones adjuntas no se
les puede asignar directamente un valor dentro de una función (a menos que, para variables
globales, se mencionen en una declaración global o, para variables de funciones adjuntas,
que se mencionen en una declaración nonlocal ), aunque pueden ser referenciado.
Los parámetros reales (argumentos) de una función se introducen en la tabla de símbolos local
de la función llamada cuando esta es ejecutada; así, los argumentos son pasados por valor
(dónde el valor es siempre una referencia a un objeto, no el valor del objeto).
En realidad, llamadas por referencia de objeto sería una mejor descripción, ya que
si se pasa un objeto mutable, quien realiza la llamada verá cualquier cambio que
se realice sobre el mismo (por ejemplo ítems insertados en una lista).
Cuando una función llama a otra función, una nueva tabla de símbolos local es creada para esa
llamada.
r66/2021(MrTín) Página 23 de 82
Introducción a la
Ingeniería en Computación
2021
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
Viniendo de otros lenguajes, puedes objetar que fib no es una función, sino un procedimiento,
porque no devuelve un valor. De hecho, técnicamente hablando, los procedimientos sin
return sí retornan un valor, aunque uno aburrido. Este valor se llama None (es un nombre
predefinido). El intérprete por lo general no escribe el valor None si va a ser el único valor
escrito. Si realmente se quiere, se puede verlo usando la función print()
>>> fib(0)
>>> print(fib(0))
None
Es simple escribir una función que retorne una lista con los números de la serie de Fibonacci en
lugar de imprimirlos:
r66/2021(MrTín) Página 24 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 25 de 82
Introducción a la
Ingeniería en Computación
2021
Este ejemplo también introduce la palabra reservada in, la cual prueba si una secuencia
contiene o no un determinado valor.
Los valores por omisión son evaluados en el momento de la definición de la función, en el
ámbito de la definición, entonces:
i = 5
def f(arg=i):
print(arg)
i = 6
f()
…imprimirá `5.
Advertencia importante: El valor por omisión es evaluado solo una vez. Existe una diferencia
cuando el valor por omisión es un objeto mutable como una lista, diccionario, o instancia de la
mayoría de las clases. Por ejemplo, la siguiente función acumula los argumentos que se le
pasan en subsiguientes llamadas:
print(f(1))
print(f(2))
print(f(3))
Imprimirá
[1]
[1, 2]
[1, 2, 3]
Si no se quiere que el valor por omisión sea compartido entre subsiguientes llamadas, se
pueden escribir la función así:
r66/2021(MrTín) Página 26 de 82
Introducción a la
Ingeniería en Computación
2021
return L
En una llamada a una función, los argumentos nombrados deben seguir a los argumentos
posicionales. Cada uno de los argumentos nombrados pasados deben coincidir con un
argumento aceptado por la función (por ejemplo, actor no es un argumento válido para la
función parrot), y el orden de los mismos no es importante. Esto también se aplica a los
argumentos obligatorios (por ejemplo, parrot(voltage=1000) también es válido).
Ningún argumento puede recibir más de un valor al mismo tiempo. Aquí hay un ejemplo que falla
debido a esta restricción:
r66/2021(MrTín) Página 27 de 82
Introducción a la
Ingeniería en Computación
2021
... pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function() got multiple values for keyword argument 'a'
Cuando un parámetro formal final en la forma **name está presente, recibe un diccionario (ver
Mapping Types — dict) conteniendo todos los argumento de palabra clave excepto aquellos que
correspondan al argumento formal. Esto puede ser combinado con el parámetro formal del tipo
*name (descrito en la siguiente sección) el cual recibe una tuple conteniendo los argumentos
posicionales mas alla de la lista de parámetros formal (*name debe estar antes que **name.).
Por ejemplo, si definimos una función de la siguiente manera:
Se debe notar que el orden en el cual los argumentos nombrados son impresos está garantizado
para coincidir con el orden en el cual fueron provistos en la llamada a la función.
r66/2021(MrTín) Página 28 de 82
Introducción a la
Ingeniería en Computación
2021
Normalmente estos argumentos de cantidad variables son los últimos en la lista de parámetros
formales, porque toman todo el remanente de argumentos que se pasan a la función. Cualquier
parámetro que suceda luego del *args será “sólo nombrado”, o sea que sólo se pueden usar
como argumentos nombrados y no como posicionales.:
Del mismo modo, los diccionarios pueden entregar argumentos nombrados con el operador **:
r66/2021(MrTín) Página 29 de 82
Introducción a la
Ingeniería en Computación
2021
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action":
"VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's
bleedin' demised !
Expresiones lambda
Pequeñas funciones anónimas pueden ser creadas con la palabra reservada lambda. Esta
función retorna la suma de sus dos argumentos: lambda a, b: a+b Las funciones
Lambda pueden ser usadas en cualquier lugar donde sea requerido un objeto de tipo función.
Están sintácticamente restringidas a una sola expresión. Semánticamente, son solo azúcar
sintáctica para definiciones normales de funciones. Al igual que las funciones anidadas, las
funciones lambda pueden hacer referencia a variables desde el ámbito que la contiene:
El ejemplo anterior muestra el uso de una expresión lambda para retornar una función. Otro uso
es para pasar pequeñas funciones como argumentos
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
r66/2021(MrTín) Página 30 de 82
Introducción a la
Ingeniería en Computación
2021
Anotación de funciones
Las anotaciones de funciones son información completamente opcional sobre los tipos usadas
en funciones definidas por el usuario (ver PEP 484 para más información).
Las anotaciones se almacenan en el atributo __annotations__ de la función como un
diccionario y no tienen efecto en ninguna otra parte de la función. Las anotaciones de los
parámetros se definen luego de dos puntos después del nombre del parámetro, seguido de una
r66/2021(MrTín) Página 31 de 82
Introducción a la
Ingeniería en Computación
2021
expresión que evalúa al valor de la anotación. Las anotaciones de retorno son definidas por el
literal ->, seguidas de una expresión, entre la lista de parámetros y los dos puntos que marcan el
final de la declaración def. El siguiente ejemplo tiene un argumento posicional, uno nombrado,
y el valor de retorno anotado:
4 espacios son un buen compromiso entre una sangría pequeña (permite mayor nivel de
sangrado)y una sangría grande (más fácil de leer). Los tabuladores introducen confusión
y es mejor dejarlos de lado.
• Recortar las líneas para que no superen los 79 caracteres.
Esto ayuda a los usuarios con pantallas pequeñas y hace posible tener varios archivos de
código abiertos, uno al lado del otro, en pantallas grandes.
• Usar líneas en blanco para separar funciones y clases, y bloques grandes de código
dentro de funciones.
r66/2021(MrTín) Página 32 de 82
Introducción a la
Ingeniería en Computación
2021
• Usar docstrings.
r66/2021(MrTín) Página 33 de 82
Introducción a la
Ingeniería en Computación
2021
Estructuras de datos
Este capítulo describe algunas cosas que ya has aprendido en más detalle y agrega algunas
cosas nuevas también.
list.append(x)
list.extend(iterable)
Extiende la lista agregándole todos los ítems del iterable. Equivale a a[len(a):] =
iterable.
list.insert(i, x)
Inserta un ítem en una posición dada. El primer argumento es el índice del ítem delante del
cual se insertará, por lo tanto a.insert(0, x) inserta al principio de la lista y
a.insert(len(a), x) equivale a a.append(x).
list.remove(x)
Quita el primer ítem de la lista cuyo valor sea x. Lanza un ValueError si no existe tal
ítem.
list.pop([i])
r66/2021(MrTín) Página 34 de 82
Introducción a la
Ingeniería en Computación
2021
list.clear()
Devuelve el índice basado en cero del primer elemento cuyo valor sea igual a x. Lanza una
excepción ValueError si no existe tal elemento.
Los argumentos opcionales start y end son interpretados como la notación de rebanadas y
se usan para limitar la búsqueda a un segmento particular de la lista. El índice devuelto se
calcula de manera relativa al inicio de la secuencia completa en lugar de con respecto al
argumento start.
list.count(x)
list.sort(key=None, reverse=False)
Ordena los elementos de la lista in situ (los argumentos pueden ser usados para
personalizar el orden de la lista, ver sorted() para su explicación).
list.reverse()
list.copy()
r66/2021(MrTín) Página 35 de 82
Introducción a la
Ingeniería en Computación
2021
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'
Quizás hayas notado que métodos como insert`, remove o sort que únicamente modifican
la lista no tienen impreso un valor de retorno – devuelven el valor por defecto None.
Esto es un principio de diseño para todas las estructuras de datos mutables en Python.
r66/2021(MrTín) Página 36 de 82
Introducción a la
Ingeniería en Computación
2021
Comprensión de listas
Las comprensiones de listas ofrecen una manera concisa de crear listas. Sus usos comunes son
para hacer nuevas listas donde cada elemento es el resultado de algunas operaciones aplicadas
a cada miembro de otra secuencia o iterable, o para crear un segmento de la secuencia de esos
elementos para satisfacer una condición determinada.
Por ejemplo, asumamos que queremos crear una lista de cuadrados, como:
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Nota que esto crea (o sobreescribe) una variable llamada x que sigue existiendo luego de que el
bucle haya terminado. Podemos calcular la lista de cuadrados sin ningun efecto secundario
haciendo:
r66/2021(MrTín) Página 37 de 82
Introducción a la
Ingeniería en Computación
2021
o, un equivalente:
y es equivalente a:
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Si la expresión es una tupla (como el (x, y) en el ejemplo anterior), debe estar entre
paréntesis.
r66/2021(MrTín) Página 38 de 82
Introducción a la
Ingeniería en Computación
2021
>>> matrix = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]
Como vimos en la sección anterior, la lista de comprensión anidada se evalua en el contexto del
for que lo sigue, por lo que este ejemplo equivale a:
r66/2021(MrTín) Página 39 de 82
Introducción a la
Ingeniería en Computación
2021
>>> transposed = []
>>> for i in range(4):
... transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
>>> transposed = []
>>> for i in range(4):
... # the following 3 lines implement the nested listcomp
... transposed_row = []
... for row in matrix:
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
En el mundo real, deberías preferir funciones predefinidas a declaraciones con flujo complejo. La
función zip() haría un buen trabajo para este caso de uso:
>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
Ver Desempaquetando una lista de argumentos para detalles en el asterisco de esta línea.
La instrucción del
Hay una manera de quitar un ítem de una lista dado su índice en lugar de su valor: la instrucción
del. Esta es diferente del método pop(), el cual devuelve un valor. La instrucción del
también puede usarse para quitar secciones de una lista o vaciar la lista completa (lo que
hacíamos antes asignando una lista vacía a la sección). Por ejemplo:
r66/2021(MrTín) Página 40 de 82
Introducción a la
Ingeniería en Computación
2021
[]
>>> del a
Hacer referencia al nombre a de aquí en más es un error (al menos hasta que se le asigne otro
valor). Veremos otros usos para del más adelante.
Tuplas y secuencias
Vimos que las listas y cadenas tienen propiedades en común, como el indizado y las
operaciones de seccionado. Estas son dos ejemplos de datos de tipo secuencia (ver Sequence
Types — list, tuple, range). Como Python es un lenguaje en evolución, otros datos de tipo
secuencia pueden agregarse. Existe otro dato de tipo secuencia estándar: la tupla.
Una tupla consiste de un número de valores separados por comas, por ejemplo:
Como puedes ver, en la salida las tuplas siempre se encierran entre paréntesis, para que las
tuplas anidadas puedan interpretarse correctamente; pueden ingresarse con o sin paréntesis,
aunque a menudo los paréntesis son necesarios de todas formas (si la tupla es parte de una
expresión más grande). No es posible asignar a los ítems individuales de una tupla, pero sin
embargo sí se puede crear tuplas que contengan objetos mutables, como las listas.
r66/2021(MrTín) Página 41 de 82
Introducción a la
Ingeniería en Computación
2021
A pesar de que las tuplas puedan parecerse a las listas, frecuentemente se utilizan en distintas
situaciones y para distintos propósitos. Las tuplas son inmutables y normalmente contienen una
secuencia heterogénea de elementos que son accedidos al desempaquetar (ver más adelante
en esta sección) o indizar (o incluso acceder por atributo en el caso de las namedtuples).
Las listas son mutables, y sus elementos son normalmente homogéneos y se acceden iterando
a la lista.
Un problema particular es la construcción de tuplas que contengan 0 o 1 ítem: la sintaxis
presenta algunas peculiaridades para estos casos. Las tuplas vacías se construyen mediante un
par de paréntesis vacío; una tupla con un ítem se construye poniendo una coma a continuación
del valor (no alcanza con encerrar un único valor entre paréntesis). Feo, pero efectivo. Por
ejemplo:
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
r66/2021(MrTín) Página 42 de 82
Introducción a la
Ingeniería en Computación
2021
Conjuntos
Python también incluye un tipo de dato para conjuntos. Un conjunto es una colección no
ordenada y sin elementos repetidos. Los usos básicos de éstos incluyen verificación de
pertenencia y eliminación de entradas duplicadas. Los conjuntos también soportan operaciones
matemáticas como la unión, intersección, diferencia, y diferencia simétrica.
Las llaves o la función set() pueden usarse para crear conjuntos. Notá que para crear un
conjunto vacío tenés que usar set(), no {}; esto último crea un diccionario vacío, una
estructura de datos que discutiremos en la sección siguiente.
Una pequeña demostración:
r66/2021(MrTín) Página 43 de 82
Introducción a la
Ingeniería en Computación
2021
Diccionarios
Otro tipo de dato útil incluído en Python es el diccionario (ver Mapping Types — dict). Los
diccionarios se encuentran a veces en otros lenguajes como «memorias asociativas» o
«arreglos asociativos». A diferencia de las secuencias, que se indexan mediante un rango
numérico, los diccionarios se indexan con claves, que pueden ser cualquier tipo inmutable; las
cadenas y números siempre pueden ser claves. Las tuplas pueden usarse como claves si
solamente contienen cadenas, números o tuplas; si una tupla contiene cualquier objeto mutable
directa o indirectamente, no puede usarse como clave. No podés usar listas como claves, ya que
las listas pueden modificarse usando asignación por índice, asignación por sección, o métodos
como append() y extend().
r66/2021(MrTín) Página 44 de 82
Introducción a la
Ingeniería en Computación
2021
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
Además, las comprensiones de diccionarios se pueden usar para crear diccionarios desde
expresiones arbitrarias de clave y valor:
Cuando las claves son cadenas simples, a veces resulta más fácil especificar los pares usando
argumentos por palabra clave:
Técnicas de iteración
Cuando iteramos sobre diccionarios, se pueden obtener al mismo tiempo la clave y su valor
correspondiente usando el método items().
Cuando se itera sobre una secuencia, se puede obtener el índice de posición junto a su valor
correspondiente usando la función enumerate().
r66/2021(MrTín) Página 45 de 82
Introducción a la
Ingeniería en Computación
2021
Para iterar sobre dos o más secuencias al mismo tiempo, los valores pueden emparejarse con la
función zip().
Para iterar sobre una secuencia en orden inverso, se especifica primero la secuencia al derecho
y luego se llama a la función reversed().
Para iterar sobre una secuencia ordenada, se utiliza la función sorted() la cual devuelve una
nueva lista ordenada dejando a la original intacta.
A veces uno intenta cambiar una lista mientras la está iterando; sin embargo, a menudo es más
simple y seguro crear una nueva lista:
r66/2021(MrTín) Página 46 de 82
Introducción a la
Ingeniería en Computación
2021
Las comparaciones pueden combinarse mediante los operadores booleanos and y or, y el
resultado de una comparación (o de cualquier otra expresión booleana) puede negarse con
not. Estos tienen prioridades menores que los operadores de comparación; entre ellos not
tiene la mayor prioridad y or la menor, o sea que A and not B or C equivale a (A and
(not B)) or C. Como siempre, los paréntesis pueden usarse para expresar la composición
deseada.
Los operadores booleanos and y or son los llamados operadores cortocircuito: sus
argumentos se evalúan de izquierda a derecha, y la evaluación se detiene en el momento en que
se determina su resultado. Por ejemplo, si A y C son verdaderas pero B es falsa, en A and B
and C no se evalúa la expresión C. Cuando se usa como un valor general y no como un
booleano, el valor devuelto de un operador cortocircuito es el último argumento evaluado.
Es posible asignar el resultado de una comparación u otra expresión booleana a una variable.
Por ejemplo,
r66/2021(MrTín) Página 47 de 82
Introducción a la
Ingeniería en Computación
2021
Notá que en Python, a diferencia de C, la asignación no puede ocurrir dentro de expresiones. Los
programadores de C pueden renegar por esto, pero es algo que evita un tipo de problema
común encontrado en programas en C: escribir = en una expresión cuando lo que se quiere
escribir es ==.
Observá que comparar objetos de diferentes tipos con < o > es legal siempre y cuando los
objetas tenga los métodos de comparación apropiados. Por ejemplo, los tipos de números
mezclados son comparados de acuerdo a su valor numérico, o sea 0 es igual a 0.0, etc. Si no es
el caso, en lugar de proveer un ordenamiento arbitrario, el intérprete generará una excepción
TypeError.
r66/2021(MrTín) Página 48 de 82
Introducción a la
Ingeniería en Computación
2021
Errores y excepciones
Hasta ahora los mensajes de error apenas habían sido mencionados, pero si has probado los
ejemplos anteriores probablemente hayas visto algunos. Hay (al menos) dos tipos diferentes de
errores: errores de sintaxis y excepciones.
Errores de sintaxis
Los errores de sintaxis, también conocidos como errores de interpretación, son quizás el tipo de
queja más común que tenés cuando todavía estás aprendiendo Python:
El intérprete reproduce la línea responsable del error y muestra una pequeña “flecha” que
apunta al primer lugar donde se detectó el error. El error ha sido provocado (o al menos
detectado) en el elemento que precede a la flecha: en el ejemplo, el error se detecta en la
función print(), ya que faltan dos puntos (':') antes del mismo. Se muestran el nombre del
archivo y el número de línea para que sepas dónde mirar en caso de que la entrada venga de un
programa.
Excepciones
Incluso si una declaración o expresión es sintácticamente correcta, puede generar un error
cuando se intenta ejecutar. Los errores detectados durante la ejecución se llaman excepciones,
y no son incondicionalmente fatales: pronto aprenderás a gestionarlos en programas Python. Sin
embargo, la mayoría de las excepciones no son gestionadas por el código, y resultan en
mensajes de error como los mostrados aquí:
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
r66/2021(MrTín) Página 49 de 82
Introducción a la
Ingeniería en Computación
2021
La última línea de los mensajes de error indica qué ha sucedido. Hay excepciones de diferentes
tipos, y el tipo se imprime como parte del mensaje: los tipos en el ejemplo son:
ZeroDivisionError, NameError y TypeError. La cadena mostrada como tipo de la
excepción es el nombre de la excepción predefinida que ha ocurrido. Esto es válido para todas
las excepciones predefinidas del intérprete, pero no tiene por que ser así para excepciones
definidas por el usuario (aunque es una convención útil). Los nombres de las excepciones
estándar son identificadores incorporados al intérprete (no son palabras clave reservadas).
El resto de la línea provee información basado en el tipo de la excepción y qué la causó.
La parte anterior del mensaje de error muestra el contexto donde ha sucedido la excepción, en
formato de traza de error. En general, contiene una traza de error que lista líneas de código
fuente; sin embargo, no mostrará líneas leídas desde la entrada estándar.
Built-in Exceptions lista las excepciones predefinidas y sus significados.
Gestionando Excepciones
Es posible escribir programas que gestionen determinadas excepciones. Mirá el siguiente
ejemplo, que le pide al usuario una entrada hasta que ingrese un entero válido, pero permite al
usuario interrumpir el programa (usando Control-C o lo que sea que el sistema operativo
soporte); notá que una interrupción generada por el usuario se señaliza generando la excepción
KeyboardInterrupt.
r66/2021(MrTín) Página 50 de 82
Introducción a la
Ingeniería en Computación
2021
• Primero, se ejecuta la cláusula try (la(s) linea(s) entre las palabras reservadas try y la
except).
• Si ocurre una excepción que no coincide con la indicada en la cláusula except se pasa a
los try más externos; si no se encuentra un gestor, se genera una unhandled exception
(excepción no gestionada) y la ejecución se interrumpen con un mensaje como el que se
muestra arriba.
Una declaración try puede tener más de un except, para especificar gestores para distintas
excepciones. A lo sumo un bloque será ejecutado. Sólo se gestionarán excepciones que ocurren
en el correspondiente try, no en otros bloques del mismo try. Un except puede nombrar
múltiples excepciones usando paréntesis, por ejemplo:
Una clase en una cláusula except es compatible con una excepción si la misma está en la
misma clase o una clase base de la misma (pero no de la otra manera — una clausula except
listando una clase derivada no es compatible con una clase base). Por ejemplo, el siguiente
código imprimirá B, C y D, en ese orden:
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
r66/2021(MrTín) Página 51 de 82
Introducción a la
Ingeniería en Computación
2021
print("D")
except C:
print("C")
except B:
print("B")
Nótese que si las cláusulas except estuvieran invertidas (con except B primero), habría
impreso B, B, B — se usa la primera cláusula except coincidente.
El último except puede omitir el nombre de la excepción capturada y servir como comodín.
Usá esto con extremo cuidado, ya que de esta manera es fácil ocultar un error real de
programación. También puede usarse para mostrar un mensaje de error y luego re-generar la
excepción (permitiéndole al que llama, gestionar también la excepción):
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
Las declaraciones try … except tienen un bloque else opcional, el cual, cuando está
presente, debe seguir a los except. Es útil para aquel código que debe ejecutarse si el bloque try
no genera una excepción. Por ejemplo:
El uso de la cláusula else es mejor que agregar código adicional en la cláusula try porque
evita capturar accidentalmente una excepción que no fue generada por el código que está
protegido por la declaración try … except.
r66/2021(MrTín) Página 52 de 82
Introducción a la
Ingeniería en Computación
2021
Cuando ocurre una excepción, puede tener un valor asociado, también conocido como el
argumento de la excepción. La presencia y el tipo de argumento depende del tipo de excepción.
El except puede especificar una variable luego del nombre de excepción. La variable se
vincula a una instancia de excepción con los argumentos almacenados en instance.args.
Por conveniencia, la instancia de excepción define __str__() para que se pueda mostrar los
argumentos directamente, sin necesidad de hacer referencia a .args. También se puede
instanciar la excepción primero, antes de generarla, y agregarle los atributos que se desee:
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
Si una excepción tiene argumentos, estos se imprimen como en la parte final (el “detalle”) del
mensaje para las excepciones no gestionadas (“Unhandled exception”).
Los gestores de excepciones no gestionan solamente las excepciones que ocurren en el bloque
try, también gestionan las excepciones que ocurren dentro de las funciones que se llaman
(inclusive indirectamente) dentro del bloque try. Por ejemplo:
r66/2021(MrTín) Página 53 de 82
Introducción a la
Ingeniería en Computación
2021
Lanzando excepciones
La declaración raise permite al programador forzar a que ocurra una excepción específica.
Por ejemplo:
El único argumento de raise indica la excepción a generarse. Tiene que ser o una instancia de
excepción, o una clase de excepción (una clase que hereda de Exception). Si se pasa una
clase de excepción, la misma será instanciada implícitamente llamando a su constructor sin
argumentos:
raise ValueError # shorthand for 'raise ValueError()'
Si necesitás determinar si una excepción fue lanzada pero no querés gestionarla, una versión
simplificada de la instrucción raise te permite relanzarla:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere
Encadenando Excepciones
La sentencia raise permite un opcional from que permite encadenar excepciones: Por
ejemplo:
r66/2021(MrTín) Página 54 de 82
Introducción a la
Ingeniería en Computación
2021
The above exception was the direct cause of the following exception:
try:
open('database.sqlite')
except IOError:
raise RuntimeError from None
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError
Las clases de Excepción pueden ser definidas de la misma forma que cualquier otra clase, pero
es habitual mantenerlas lo más simples posible, a menudo ofreciendo solo un número de
atributos con información sobre el error que leerán los gestores de la excepción. Al crear un
módulo que puede lanzar varios errores distintos, una práctica común es crear una clase base
r66/2021(MrTín) Página 55 de 82
Introducción a la
Ingeniería en Computación
2021
para excepciones definidas en ese módulo y extenderla para crear clases excepciones
específicas para distintas condiciones de error:
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
La mayoría de las excepciones se definen con nombres acabados en «Error», de manera similar
a la nomenclatura de las excepciones estándar.
Muchos módulos estándar definen sus propias excepciones para reportar errores que pueden
ocurrir en funciones propias. Se puede encontrar más información sobre clases en el capítulo
Clases.
r66/2021(MrTín) Página 56 de 82
Introducción a la
Ingeniería en Computación
2021
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
Si la clausula finally esta presente, esta se ejecutará inmediatamente antes del bloque
try. La clausula finally se ejecuta antes de try por esta necesita generar una excepcion
o relanzarla.
Aquí algunos casos mas complejos de cuando se puede generar una excpcion:
• Si se lanza una excepción dentro del bloque try, la excepcion puede ser gestionada por
un bloque except. Pero si la misma no es tratada por un bloque except, la
excepción es vuelta a lanzar luego de que el bloque finally ha sido ejecutado.
• Es posible que se produzca una excepcion dentro de los bloques except o else.
Nuevamente, la excepción es vuelta a lanzar luego de que el bloque finally ha sido
ejecutado.
• Si el bloque try alcanza una instrucción break, continue o return, el bloque
finally se ejecutará inmediatamente antes que dichas instrucciones.
• Si una clasula finally incluye un return, el valor retornado será el que se encuentre
generado por el return del bloque finally y no el valor del return del bloque
try.
Por ejemplo:
r66/2021(MrTín) Página 57 de 82
Introducción a la
Ingeniería en Computación
2021
En aplicaciones reales, la cláusula finally es útil para liberar recursos externos (como
archivos o conexiones de red), sin importar si el uso del recurso fue exitoso.
El problema con este código es que deja el archivo abierto por un periodo de tiempo
indeterminado luego de que esta parte termine de ejecutarse. Esto no es un problema en
scripts simples, pero puede ser un problema en aplicaciones más grandes. La declaración with
permite que los objetos como archivos sean usados de una forma que asegure que siempre se
los libera rápido y en forma correcta.:
r66/2021(MrTín) Página 58 de 82
Introducción a la
Ingeniería en Computación
2021
with open("myfile.txt") as f:
for line in f:
print(line, end="")
Una vez que la declaración se ejecuta, el fichero f siempre se cierra, incluso si aparece algún
error durante el procesado de las líneas. Los objetos que, como los ficheros, posean acciones
predefinidas de limpieza lo indicarán en su documentación.
r66/2021(MrTín) Página 59 de 82
Introducción a la
Ingeniería en Computación
2021
Glosario
>>>
El prompt en el shell interactivo de Python por omisión. Frecuentemente vistos en
ejemplos de código que pueden ser ejecutados interactivamente en el intérprete.
...
El prompth por defecto en un shell interactivo de Python cuando se está ingresando
código en un bloque con sangría (con indentación), cuando está dentro de un par de
delimitadores izquierdo y derecho coincidentes (paréntesis, corchetes, llaves o comillas
triples), o después de especificar un decorador.
2to3
Una herramienta que intenta convertir código de Python 2.x a Python 3.x arreglando la
mayoría de las incompatibilidades que pueden ser detectadas analizando el código y
recorriendo el árbol de análisis sintáctico.
2to3 está disponible en la biblioteca estándar como lib2to3; un punto de entrada
independiente es provisto como Tools/scripts/2to3. Vea 2to3 - Automated
Python 2 to 3 code translation.
clase base abstracta
Las clases base abstractas (ABC, por sus siglas en inglés Abstract Base Class)
complementan al duck-typing brindando un forma de definir interfaces con técnicas como
hasattr() que serían confusas o sutilmente erróneas (por ejemplo con magic
methods). Las ABC introduce subclases virtuales, las cuales son clases que no heredan
desde una clase pero aún así son reconocidas por isinstance() y
issubclass(); vea la documentación del módulo abc. Python viene con muchas ABC
incorporadas para las estructuras de datos( en el módulo collections.abc),
números (en el módulo numbers ) , flujos de datos (en el módulo io ) , buscadores y
cargadores de importaciones (en el módulo importlib.abc ) . Puede crear sus
propios ABCs con el módulo abc.
anotación
Una etiqueta asociada a una variable, atributo de clase, parámetro de función o valor de
retorno, usado por convención como un type hint.
Las anotaciones de variables no pueden ser accedidas en tiempo de ejecución, pero las
anotaciones de variables globales, atributos de clase, y funciones son almacenadas en el
atributo especial __annotations__ de módulos, clases y funciones,
respectivamente.
r66/2021(MrTín) Página 60 de 82
Introducción a la
Ingeniería en Computación
2021
Vea variable annotation, function annotation, PEP 484 y PEP 526, los cuales describen
esta funcionalidad.
argumento
Un valor pasado a una function (o method) cuando se llama a la función. Hay dos clases
de argumentos:
• argumento nombrado: es un argumento precedido por un identificador (por ejemplo,
nombre=) en una llamada a una función o pasado como valor en un diccionario
precedido por **. Por ejemplo 3 y 5 son argumentos nombrados en las llamadas a
complex():
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})
complex(3, 5)
complex(*(3, 5))
Los argumentos son asignados a las variables locales en el cuerpo de la función. Vea en la
sección Calls las reglas que rigen estas asignaciones. Sintácticamente, cualquier
expresión puede ser usada para representar un argumento; el valor evaluado es asignado
a la variable local.
Vea también el parameter en el glosario, la pregunta frecuente la diferencia entre
argumentos y parámetros, y PEP 362.
administrador asincrónico de contexto
Un objeto que controla el entorno visible en un sentencia async with al definir los
métodos __aenter__() __aexit__(). Introducido por PEP 492.
generador asincrónico
Una función que retorna un asynchronous generator iterator. Es similar a una función
corrutina definida con async def excepto que contiene expresiones yield para
producir series de variables usadas en un ciclo async for.
Usualmente se refiere a una función generadora asincrónica, pero puede referirse a un
iterador generador asincrónico en ciertos contextos. En aquellos casos en los que el
significado no está claro, usar los términos completos evita la ambigüedad.
r66/2021(MrTín) Página 61 de 82
Introducción a la
Ingeniería en Computación
2021
Una función generadora asincrónica puede contener expresiones await así como
sentencias async for, y async with.
iterador generador asincrónico
Un objeto creado por una función asynchronous generator.
Este es un asynchronous iterator el cual cuando es llamado usa el método
__anext__() retornando un objeto aguardable el cual ejecutará el cuerpo de la
función generadora asincrónica hasta la siguiente expresión yield.
Cada yield suspende temporalmente el procesamiento, recordando el estado local de
ejecución (incluyendo a las variables locales y las sentencias try pendientes). Cuando el
iterador del generador asincrónico vuelve efectivamente con otro aguardable retornado
por el método __anext__(), retoma donde lo dejó. Vea PEP 492 y PEP 525.
iterable asincrónico
Un objeto, que puede ser usado en una sentencia async for. Debe retornar un
asynchronous iterator de su método __aiter__(). Introducido por PEP 492.
iterador asincrónico
Un objeto que implementa los métodos meth:__aiter__ y __anext__(). __anext__
debe retornar un objeto awaitable. async for resuelve los esperables retornados por
un método de iterador asincrónico __anext__() hasta que lanza una excepción
StopAsyncIteration. Introducido por PEP 492.
atributo
Un valor asociado a un objeto que es referencias por el nombre usado expresiones de
punto. Por ejemplo, si un objeto o tiene un atributo a sería referenciado como o.a.
aguardable
Es un objeto que puede ser usado en una expresión await. Puede ser una coroutine o un
objeto con un método __await__(). Vea también pep:492.
BDFL
Sigla de Benevolent Dictator For Life, Benevolente dictador vitalicio, es decir Guido van
Rossum, el creador de Python.
archivo binario
Un file object capaz de leer y escribir objetos tipo binarios. Ejemplos de archivos binarios
son los abiertos en modo binario ('rb', 'wb' o 'rb+'), sys.stdin.buffer,
sys.stdout.buffer, e instancias de io.BytesIO y de gzip.GzipFile.
Vea también text file para un objeto archivo capaz de leer y escribir objetos str.
objetos tipo binarios
r66/2021(MrTín) Página 62 de 82
Introducción a la
Ingeniería en Computación
2021
Un objeto que soporta Buffer Protocol y puede exportar un buffer C-contiguous. Esto
incluye todas los objetos bytes, bytearray, y array.array, así como muchos
objetos comunes memoryview. Los objetos tipo binarios pueden ser usados para varias
operaciones que usan datos binarios; éstas incluyen compresión, salvar a archivos
binarios, y enviarlos a través de un socket.
Algunas operaciones necesitan que los datos binarios sean mutables. La documentación
frecuentemente se refiere a éstos como «objetos tipo binario de lectura y escritura».
Ejemplos de objetos de buffer mutables incluyen a bytearray y memoryview de la
bytearray. Otras operaciones que requieren datos binarios almacenados en objetos
inmutables («objetos tipo binario de sólo lectura»); ejemplos de éstos incluyen bytes y
memoryview del objeto bytes.
bytecode
El código fuente Python es compilado en bytecode, la representación interna de un
programa python en el intérprete CPython. El bytecode también es guardado en caché en
los archivos .pyc de tal forma que ejecutar el mismo archivo es más fácil la segunda vez
(la recompilación desde el código fuente a bytecode puede ser evitada). Este «lenguaje
intermedio» deberá corren en una virtual machine que ejecute el código de máquina
correspondiente a cada bytecode. Note que los bytecodes no tienen como requisito
trabajar en las diversas máquina virtuales de Python, ni de ser estable entre versiones
Python.
Una lista de las instrucciones en bytecode está disponible en la documentación de el
módulo dis.
clase
Una plantilla para crear objetos definidos por el usuario. Las definiciones de clase
normalmente contienen definiciones de métodos que operan una instancia de la clase.
variable de clase
Una variable definida en una clase y prevista para ser modificada sólo a nivel de clase (es
decir, no en una instancia de la clase).
coerción
La conversión implícita de una instancia de un tipo en otra durante una operación que
involucra dos argumentos del mismo tipo. Por ejemplo, int(3.15) convierte el número
de punto flotante al entero 3, pero en 3 + 4.5, cada argumento es de un tipo diferente
(uno entero, otro flotante), y ambos deben ser convertidos al mismo tipo antes de que
puedan ser sumados o emitiría un TypeError. Sin coerción, todos los argumentos,
incluso de tipos compatibles, deberían ser normalizados al mismo tipo por el programador,
por ejemplo float(3)+4.5 en lugar de 3+4.5.
número complejo
r66/2021(MrTín) Página 63 de 82
Introducción a la
Ingeniería en Computación
2021
Una extensión del sistema familiar de número reales en el cual los números son
expresados como la suma de una parte real y una parte imaginaria. Los números
imaginarios son múltiplos de la unidad imaginaria (la raíz cuadrada de -1), usualmente
escrita como i en matemáticas o j en ingeniería. Python tiene soporte incorporado para
números complejos, los cuales son escritos con la notación mencionada al final.; la parte
imaginaria es escrita con un sufijo j, por ejemplo, 3+1j. Para tener acceso a los
equivalentes complejos del módulo math module, use :mod:`cmath. El uso de números
complejos es matemática bastante avanzada. Si no le parecen necesarios, puede
ignorarlos sin inconvenientes.
administrador de contextos
Un objeto que controla el entorno en la sentencia with definiendo __enter__() y
__exit__() methods. Vea PEP 343.
context variable
A variable which can have different values depending on its context. This is similar to
Thread-Local Storage in which each execution thread may have a different value for a
variable. However, with context variables, there may be several contexts in one execution
thread and the main usage for context variables is to keep track of variables in concurrent
asynchronous tasks. See contextvars.
contiguo
Un buffer es considerado contiguo con precisión si es C-contíguo o Fortran contiguo. Los
buffers cero dimensionales con C y Fortran contiguos. En los arreglos unidimensionales,
los ítems deben ser dispuestos en memoria uno siguiente al otro, ordenados por índices
que comienzan en cero. En arreglos unidimensionales C-contíguos, el último índice varía
más velozmente en el orden de las direcciones de memoria. Sin embargo, en arreglos
Fortran contiguos, el primer índice vería más rápidamente.
corrutina
Coroutines are a more generalized form of subroutines. Subroutines are entered at one
point and exited at another point. Coroutines can be entered, exited, and resumed at many
different points. They can be implemented with the async def statement. See also PEP
492.
función corrutina
Un función que retorna un objeto coroutine . Una función corrutina puede ser definida con
la sentencia async def, y puede contener las palabras claves await, async for, y
async with. Las mismas son introducidas en PEP 492.
CPython
r66/2021(MrTín) Página 64 de 82
Introducción a la
Ingeniería en Computación
2021
def f(...):
...
f = staticmethod(f)
@staticmethod
def f(...):
...
El mismo concepto existe para clases, pero son menos usadas. Vea la documentación de
function definitions y class definitions para mayor detalle sobre decoradores.
descriptor
Cualquier objeto que define los métodos __get__(), __set__(), o
__delete__(). Cuando un atributo de clase es un descriptor, su conducta enlazada
especial es disparada durante la búsqueda del atributo. Normalmente, usando a.b para
consultar, establecer o borrar un atributo busca el objeto llamado b en el diccionario de
clase de a, pero si b es un descriptor, el respectivo método descriptor es llamado. Entender
descriptores es clave para lograr una comprensión profunda de Python porque son la base
de muchas de las capacidades incluyendo funciones, métodos, propiedades, métodos de
clase, métodos estáticos, y referencia a súper clases.
Para más información sobre métodos descriptores, vea Implementing Descriptors.
diccionario
Un arreglo asociativo, con claves arbitrarias que son asociadas a valores. Las claves
pueden ser cualquier objeto con los métodos __hash__() y __eq__() . Son llamadas
hash en Perl.
vista de diccionario
Los objetos retornados por los métodos dict.keys(), dict.values(), y
dict.items() son llamados vistas de diccionarios. Proveen una vista dinámica de las
entradas de un diccionario, lo que significa que cuando el diccionario cambia, la vista
r66/2021(MrTín) Página 65 de 82
Introducción a la
Ingeniería en Computación
2021
refleja éstos cambios. Para forzar a la vista de diccionario a convertirse en una lista
completa, use list(dictview). Vea Dictionary view objects.
docstring
Una cadena de caracteres literal que aparece como la primera expresión en una clase,
función o módulo. Aunque es ignorada cuando se ejecuta, es reconocida por el compilador
y puesta en el atributo __doc__ de la clase, función o módulo comprendida. Como está
disponible mediante introspección, es el lugar canónico para ubicar la documentación del
objeto.
tipado de pato
Un estilo de programación que no revisa el tipo del objeto para determinar si tiene la
interfaz correcta; en vez de ello, el método o atributo es simplemente llamado o usado («Si
se ve como un pato y grazna como un pato, debe ser un pato»). Enfatizando las interfaces
en vez de hacerlo con los tipos específicos, un código bien diseñado pues tener mayor
flexibilidad permitiendo la sustitución polimórfica. El tipado de pato duck-typing evita usar
pruebas llamando a type() o isinstance(). (Nota: si embargo, el tipado de pato
puede ser complementado con abstract base classes. En su lugar, generalmente emplea
hasattr() tests o EAFP.
EAFP
Del inglés «Easier to ask for forgiveness than permission», es más fácil pedir perdón que
pedir permiso. Este estilo de codificación común en Python asume la existencia de claves
o atributos válidos y atrapa las excepciones si esta suposición resulta falsa. Este estilo
rápido y limpio está caracterizado por muchas sentencias try y except. Esta técnica
contrasta con estilo LBYL usual en otros lenguajes como C.
expresión
Una construcción sintáctica que puede ser evaluada, hasta dar un valor. En otras palabras,
una expresión es una acumulación de elementos de expresión tales como literales,
nombres, accesos a atributos, operadores o llamadas a funciones, todos ellos retornando
valor. A diferencia de otros lenguajes, no toda la sintaxis del lenguaje son expresiones.
También hay statements que no pueden ser usadas como expresiones, como la while.
Las asignaciones también son sentencias, no expresiones.
módulo de extensión
Un módulo escrito en C o C++, usando la API para C de Python para interactuar con el
núcleo y el código del usuario.
f-string
Son llamadas «f-strings» las cadenas literales que usan el prefijo 'f' o 'F', que es una
abreviatura para cadenas literales formateadas. Vea también PEP 498.
r66/2021(MrTín) Página 66 de 82
Introducción a la
Ingeniería en Computación
2021
objeto archivo
Un objeto que expone una API orientada a archivos (con métodos como read() o
write()) al objeto subyacente. Dependiendo de la forma en la que fue creado, un objeto
archivo, puede mediar el acceso a un archivo real en el disco u otro tipo de dispositivo de
almacenamiento o de comunicación (por ejemplo, entrada/salida estándar, buffer de
memoria, sockets, pipes, etc.). Los objetos archivo son también denominados objetos tipo
archivo o flujos.
Existen tres categorías de objetos archivo: crudos raw archivos binarios, con buffer
archivos binarios y archivos de texto. Sus interfaces son definidas en el módulo io. La
forma canónica de crear objetos archivo es usando la función open().
objetos tipo archivo
Un sinónimo de file object.
buscador
Un objeto que trata de encontrar el loader para el módulo que está siendo importado.
Desde la versión 3.3 de Python, existen dos tipos de buscadores: meta buscadores de ruta
para usar con sys.meta_path, y buscadores de entradas de rutas para usar con
sys.path_hooks.
Vea PEP 302, PEP 420 y PEP 451 para mayores detalles.
división entera
Una división matemática que se redondea hacia el entero menor más cercano. El operador
de la división entera es //. Por ejemplo, la expresión 11 // 4 evalúa 2 a diferencia del
2.75 retornado por la verdadera división de números flotantes. Note que (-11) // 4
es -3 porque es -2.75 redondeado para abajo. Ver PEP 238.
función
Una serie de sentencias que retornan un valor al que las llama. También se le puede pasar
cero o más argumentos los cuales pueden ser usados en la ejecución de la misma. Vea
también parameter, method, y la sección Function definitions.
anotación de función
Una annotation del parámetro de una función o un valor de retorno.
Las anotaciones de funciones son usadas frecuentemente para type hint`s , por ejemplo,
se espera que una función tome dos argumentos de clase :class:`int y también se espera
que devuelva dos valores int:
r66/2021(MrTín) Página 67 de 82
Introducción a la
Ingeniería en Computación
2021
recolección de basura
El proceso de liberar la memoria de lo que ya no está en uso. Python realiza recolección de
basura (garbage collection) llevando la cuenta de las referencias, y el recogedor de basura
cíclico es capaz de detectar y romper las referencias cíclicas. El recogedor de basura
puede ser controlado mediante el módulo gc .
generador
Una función que retorna un generator iterator. Luce como una función normal excepto que
contiene la expresión yield para producir series de valores utilizables en un bucle for o
que pueden ser obtenidas una por una con la función next().
Usualmente se refiere a una función generadora, pero puede referirse a un iterador
generador en ciertos contextos. En aquellos casos en los que el significado no está claro,
usar los términos completos evita la ambigüedad.
iterador generador
Un objeto creado por una función generator.
Cada yield suspende temporalmente el procesamiento, recordando el estado de
ejecución local (incluyendo las variables locales y las sentencias try pendientes). Cuando
el «iterador generado» vuelve, retoma donde ha dejado, a diferencia de lo que ocurre con
las funciones que comienzan nuevamente con cada invocación.
expresión generadora
Una expresión que retorna un iterador. Luce como una expresión normal seguida por la
cláusula for definiendo así una variable de bucle, un rango y una cláusula opcional if.
La expresión combinada genera valores para la función contenedora:
r66/2021(MrTín) Página 68 de 82
Introducción a la
Ingeniería en Computación
2021
285
función genérica
Una función compuesta de muchas funciones que implementan la misma operación para
diferentes tipos. Qué implementación deberá ser usada durante la llamada a la misma es
determinado por el algoritmo de despacho.
Vea también la entrada de glosario single dispatch, el decorador
functools.singledispatch(), y PEP 443.
GIL
Vea global interpreter lock.
bloqueo global del intérprete
Mecanismo empleado por el intérprete CPython para asegurar que sólo un hilo ejecute el
bytecode Python por vez. Esto simplifica la implementación de CPython haciendo que el
modelo de objetos (incluyendo algunos críticos como dict) están implícitamente a salvo
de acceso concurrente. Bloqueando el intérprete completo se simplifica hacerlo multi-
hilos, a costa de mucho del paralelismo ofrecido por las máquinas con múltiples
procesadores.
Sin embargo, algunos módulos de extensión, tanto estándar como de terceros, están
diseñados para liberar el GIL cuando se realizan tareas computacionalmente intensivas
como la compresión o el hashing. Además, el GIL siempre es liberado cuando se hace
entrada/salida.
Esfuerzos previos hechos para crear un intérprete «sin hilos» (uno que bloquee los datos
compartidos con una granularidad mucho más fina) no han sido exitosos debido a que el
rendimiento sufrió para el caso más común de un solo procesador. Se cree que superar
este problema de rendimiento haría la implementación mucho más compleja y por tanto,
más costosa de mantener.
hash-based pyc
Un archivo cache de bytecode que usa el hash en vez de usar el tiempo de la última
modificación del archivo fuente correspondiente para determinar su validez. Vea Cached
bytecode invalidation.
Hashable (o hasheable)
Un objeto es hashable si tiene un valor de hash que nunca cambiará durante su tiempo de
vida (necesita un método __hash__() ), y puede ser comparado con otro objeto
(necesita el método __eq__() ). Los objetos hashables que se comparan iguales deben
tener el mismo número hash.
La hashabilidad hace a un objeto empleable como clave de un diccionario y miembro de un
set, porque éstas estructuras de datos usan los valores de hash internamente.
r66/2021(MrTín) Página 69 de 82
Introducción a la
Ingeniería en Computación
2021
La mayoría de los objetos inmutables built-in son hashables, mientras que los
contenedores como listas y diccionarios (que son mutables) no lo son. Los contenedores
inmutables, como tuplas y frozensets son solo hashables cuando sus elementos
contenidos son hashables también.
Los objetos que son instancias de clases definidas por el usuario hasheables por defecto.
Todos compara desiguales, excepto a si mismos. Y su valor de hash está derivado de su
id().
IDLE
El entorno integrado de desarrollo de Python, o «Integrated Development Environment for
Python». IDLE es un editor básico y un entorno de intérprete que se incluye con la
distribución estándar de Python.
inmutable
Un objeto con un valor fijo. Los objetos inmutables son números, cadenas y tuplas. Éstos
objetos no pueden ser alterados. Un nuevo objeto debe ser creado si un valor diferente ha
de ser guardado. Juegan un rol importante en lugares donde es necesario un valor de hash
constante, por ejemplo como claves de un diccionario.
ruta de importación
Una lista de las ubicaciones (o entradas de ruta) que son revisadas por path based finder
al importar módulos. Durante la importación, ésta lista de localizaciones usualmente viene
de sys.path, pero para los subpaquetes también puede incluir al atributo __path__
del paquete padre.
importar
El proceso mediante el cual el código Python dentro de un módulo se hace alcanzable
desde otro código Python en otro módulo.
importador
Un objeto que buscan y lee un módulo; un objeto que es tanto finder como loader.
interactivo
Python tiene un intérprete interactivo, lo que significa que puede ingresar sentencias y
expresiones en el prompt del intérprete, ejecutarlos de inmediato y ver sus resultados.
Sólo ejecute python sin argumentos (podría seleccionarlo desde el menú principal de su
computadora). Es una forma muy potente de probar nuevas ideas o inspeccionar módulos
y paquetes (recuerde help(x)).
interpretado
Python es un lenguaje interpretado, a diferencia de uno compilado, a pesar de que la
distinción puede ser difusa debido al compilador a bytecode. Esto significa que los
archivos fuente pueden ser corridos directamente, sin crear explícitamente un ejecutable
r66/2021(MrTín) Página 70 de 82
Introducción a la
Ingeniería en Computación
2021
que es corrido luego. Los lenguajes interpretados típicamente tienen ciclos de desarrollo y
depuración más cortos que los compilados, sin embargo sus programas suelen correr más
lentamente. Vea también interactive.
apagado del intérprete
Cuando se le solicita apagarse, el intérprete Python ingresa a un fase especial en la cual
gradualmente libera todos los recursos reservados, como módulos y varias estructuras
internas críticas. También hace varias llamadas al recolector de basura. Esto puede
disparar la ejecución de código de destructores definidos por el usuario o «weakref
callbacks». El código ejecutado durante la fase de apagado puede encontrar varias
excepciones debido a que los recursos que necesita pueden no funcionar más (ejemplos
comunes son los módulos de bibliotecas o los artefactos de advertencias «warnings
machinery»)
La principal razón para el apagado del intérpreter es que el módulo __main__ o el script
que estaba corriendo termine su ejecución.
iterable
Un objeto capaz de retornar sus miembros uno por vez. Ejemplos de iterables son todos
los tipos de secuencias (como list, str, y tuple) y algunos de tipos no secuenciales,
como dict, objeto archivo, y objetos de cualquier clase que defina con los métodos
__iter__() o con un método __getitem__() que implementen la semántica de
Sequence.
Los iterables pueden ser usados en el bucle for y en muchos otros sitios donde una
secuencia es necesaria (zip(), map(), …). Cuando un objeto iterable es pasado como
argumento a la función incorporada iter(), retorna un iterador para el objeto. Este
iterador pasa así el conjunto de valores. Cuando se usan iterables, normalmente no es
necesario llamar a la función iter() o tratar con los objetos iteradores usted mismo. La
sentencia for lo hace automáticamente por usted, creando un variable temporal sin
nombre para mantener el iterador mientras dura el bucle. Vea también iterator, sequence, y
generator.
iterador
Un objeto que representa un flujo de datos. Llamadas repetidas al método __next__()
del iterador (o al pasar la función incorporada next()) retorna ítems sucesivos del flujo.
Cuando no hay más datos disponibles, una excepción StopIteration es disparada.
En este momento, el objeto iterador está exhausto y cualquier llamada posterior al método
__next__() sólo dispara otra vez StopIteration. Los iteradores necesitan tener
un método:meth:__iter__ que retorna el objeto iterador mismo así cada iterador es también
un iterable y puede ser usado en casi todos los lugares donde los iterables son aceptados.
Una excepción importante es el código que intenta múltiples pases de iteración. Un objeto
contenedor (como la list) produce un nuevo iterador cada vez que las pasa a una
r66/2021(MrTín) Página 71 de 82
Introducción a la
Ingeniería en Computación
2021
función iter() o la usa en un blucle for. Intentar ésto con un iterador simplemente
retornaría el mismo objeto iterador exhausto usado en previas iteraciones, haciéndolo
aparecer como un contenedor vacío.
Puede encontrar más información en Iterator Types.
función clave
Una función clave o una función de colación es un invocable que retorna un valor usado
para el ordenamiento o clasificación. Por ejemplo, locale.strxfrm() es usada para
producir claves de ordenamiento que se adaptan a las convenciones específicas de
ordenamiento de un locale.
Cierta cantidad de herramientas de Python aceptan funciones clave para controlar como
los elementos son ordenados o agrupados. Incluyendo a min(), max(), sorted(),
list.sort(), heapq.merge(), heapq.nsmallest(),
heapq.nlargest(), y itertools.groupby().
Hay varias formas de crear una función clave. Por ejemplo, el método str.lower()
puede servir como función clave para ordenamientos que no distingan mayúsculas de
minúsculas. Como alternativa, una función clave puede ser realizada con una expresión
lambda como lambda r: (r[0], r[2]). También, el módulo operator
provee tres constructores de funciones clave: attrgetter(), itemgetter(), y
methodcaller(). Vea en Sorting HOW TO ejemplos de cómo crear y usar funciones
clave.
argumento nombrado
Vea argument.
lambda
Una función anónima de una línea consistente en un sola expression que es evaluada
cuando la función es llamada. La sintaxis para crear una función lambda es lambda
[parameters]: expression
LBYL
Del inglés «Look before you leap», «mira antes de saltar». Es un estilo de codificación que
prueba explícitamente las condiciones previas antes de hacer llamadas o búsquedas. Este
estilo contrasta con la manera EAFP y está caracterizado por la presencia de muchas
sentencias if.
En entornos multi-hilos, el método LBYL tiene el riesgo de introducir condiciones de
carrera entre los hilos que están «mirando» y los que están «saltando». Por ejemplo, el
código, if key in mapping: return mapping[key]` puede fallar si otro hilo remueve key de
mapping después del test, pero antes de retornar el valor. Este problema puede ser
resuelto usando bloqueos o empleando el método EAFP.
lista
r66/2021(MrTín) Página 72 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 73 de 82
Introducción a la
Ingeniería en Computación
2021
Una función que es definida dentro del cuerpo de una clase. Si es llamada como un
atributo de una instancia de otra clase, el método tomará el objeto instanciado como su
primer argument (el cual es usualmente denominado self). Vea function y nested scope.
orden de resolución de métodos
Orden de resolución de métodos es el orden en el cual una clase base es buscada por un
miembro durante la búsqueda. Mire en The Python 2.3 Method Resolution Order los
detalles del algoritmo usado por el intérprete Python desde la versión 2.3.
módulo
Un objeto que sirve como unidad de organización del código Python. Los módulos tienen
espacios de nombres conteniendo objetos Python arbitrarios. Los módulos son cargados
en Python por el proceso de importing.
Vea también package.
especificador de módulo
Un espacio de nombres que contiene la información relacionada a la importación usada al
leer un módulo. Una instancia de importlib.machinery.ModuleSpec.
MRO
Vea method resolution order.
mutable
Los objetos mutables pueden cambiar su valor pero mantener su id(). Vea también
immutable.
tupla nombrada
El termino «tupla nombrada» aplica a cualquier tipo o clase que hereda de tupla y cuyos
elementos indexables son también accesibles por medio de atributos con nombre.
Asimismo, dicho tipo o clase tal vez tenga funcionalidad adicional
Varios tipos built-in son tuplas nombradas, incluyendo los valores retornados por
time.localtime() y os.stat(). Otro ejemplo es sys.float_info:
Algunas tuplas con nombre son de tipos built-in, como los ejemplos anteriores. Pero
también es posible crear una a partir de una definicion de clases normal heredando de
tuple y definiendo los campos nombrados. Dicha clase puede ser desarrollada
puntualmente y a mano o puede ser creada a partir de la función fabrica
r66/2021(MrTín) Página 74 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 75 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 76 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 77 de 82
Introducción a la
Ingeniería en Computación
2021
for i in range(len(food)):
print(food[i])
nombre calificado
Un nombre con puntos mostrando la ruta desde el alcance global del módulo a la clase,
función o método definido en dicho módulo, como se define en PEP 3155. Para las
funciones o clases de más alto nivel, el nombre calificado es el igual al nombre del objeto:
>>> class C:
... class D:
r66/2021(MrTín) Página 78 de 82
Introducción a la
Ingeniería en Computación
2021
Cuando es usado para referirse a los módulos, nombre completamente calificado significa
la ruta con puntos completo al módulo, incluyendo cualquier paquete padre, por ejemplo,
email.mime.text`:
contador de referencias
El número de referencias a un objeto. Cuando el contador de referencias de un objeto cae
hasta cero, éste es desalojable. En conteo de referencias no suele ser visible en el código
de Python, pero es un elemento clave para la implementación de CPython. El módulo sys
define la getrefcount() que los programadores pueden emplear para retornar el
conteo de referencias de un objeto en particular.
paquete regular
Un package tradicional, como aquellos con un directorio conteniendo el archivo
__init__.py.
Vea también namespace package.
__slots__
Es una declaración dentro de una clase que ahorra memoria pre declarando espacio para
las atributos de la instancia y eliminando diccionarios de la instancia. Aunque es popular,
esta técnica es algo dificultosa de lograr correctamente y es mejor reservarla para los
casos raros en los que existen grandes cantidades de instancias en aplicaciones con uso
crítico de memoria.
secuencia
Un iterable que logra un acceso eficiente a los elementos usando índices enteros a través
del método especial __getitem__() y que define un método __len__() que
devuelve la longitud de la secuencia. Algunas de las secuencias incorporadas son list,
str, tuple, y bytes. Observe que dict también soporta __getitem__() y
__len__(), pero es considerada un mapeo más que una secuencia porque las
búsquedas son por claves arbitraria immutable y no por enteros.
r66/2021(MrTín) Página 79 de 82
Introducción a la
Ingeniería en Computación
2021
r66/2021(MrTín) Página 80 de 82
Introducción a la
Ingeniería en Computación
2021
tipo
El tipo de un objeto Python determina qué tipo de objeto es; cada objeto tiene un tipo. El
tipo de un objeto puede ser accedido por su atributo __class__ o puede ser
conseguido usando type(obj).
alias de tipos
Un sinónimo para un tipo, creado al asignar un tipo a un identificador.
Los alias de tipos son útiles para simplificar los indicadores de tipo. Por ejemplo:
def remove_gray_shades(
colors: List[Tuple[int, int, int]]) -> List[Tuple[int, int, int]]:
pass
r66/2021(MrTín) Página 81 de 82
Introducción a la
Ingeniería en Computación
2021
class C:
field: 'annotation'
Las anotaciones de variables son frecuentemente usadas para type hints: por ejemplo, se
espera que esta variable tenga valores de clase int:
count: int = 0
r66/2021(MrTín) Página 82 de 82