¿Qué se entiende por "usar el principio EAFP" en Python? ¿Podría darnos algún ejemplo?
¿Qué se entiende por "usar el principio EAFP" en Python? ¿Podría darnos algún ejemplo?
Respuestas:
Del glosario :
Es más fácil pedir perdón que permiso. Este estilo común de codificación de Python supone la existencia de claves o atributos válidos y captura excepciones si el supuesto resulta falso. Este estilo limpio y rápido se caracteriza por la presencia de muchos
try
yexcept
declaraciones. La técnica contrasta con el estilo LBYL común a muchos otros lenguajes como C.
Un ejemplo sería un intento de acceder a una clave de diccionario.
EAFP:
try:
x = my_dict["key"]
except KeyError:
# handle missing key
LBYL:
if "key" in my_dict:
x = my_dict["key"]
else:
# handle missing key
La versión LBYL tiene que buscar la clave dentro del diccionario dos veces, y también podría considerarse un poco menos legible.
x
cuando la clave no existe: x = mydict.get('key')
regresará None
si 'key'
no está en my_dict
; también podría hacerlo .get('key', <something>)
, y luego se le asignará algo a x si la clave no está en el diccionario. dict.setdefault()
y collections.defaultdict
son cosas buenas para evitar el exceso de código también.
except KeyError
al igual que AttributeError
son simples pero algunos de los peores ejemplos. Muchas veces me quedé atrapado depurando algo porque except AttributeError
se colocó en el lugar incorrecto, lo que terminó atrapando un error de atributo incorrecto que se elevó más profundamente en la cadena. Mejores ejemplos creo que son: try: open() ... except: IOError
. O bientry: parseLine() ... except ParseError
Trataré de explicarlo con otro ejemplo.
Aquí estamos intentando acceder al archivo e imprimir el contenido en la consola.
Es posible que deseemos verificar si podemos acceder al archivo y, si podemos, lo abriremos e imprimiremos el contenido. Si no podemos acceder al archivo, tocaremos la else
parte. La razón por la cual esta es una condición de carrera es porque primero hacemos una verificación de acceso. Para cuando lleguemos, with open(my_file) as f:
tal vez ya no podamos acceder a él debido a algunos problemas de permisos (por ejemplo, otro proceso obtiene un bloqueo de archivo exclusivo). Es probable que este código arroje un error y no podremos detectarlo porque pensamos que podríamos acceder al archivo.
import os
my_file = "/path/to/my/file.txt"
# Race condition
if os.access(my_file, os.R_OK):
with open(my_file) as f:
print(f.read())
else:
print("File can't be accessed")
En este ejemplo, solo estamos tratando de abrir el archivo y si no podemos abrirlo, arrojará un IOError
. Si podemos, abriremos el archivo e imprimiremos el contenido. Entonces, en lugar de preguntar algo, estamos tratando de hacerlo. Si funciona, ¡genial! Si no es así, detectamos el error y lo manejamos.
# # No race condition
try:
f = open(my_file)
except IOError as e:
print("File can't be accessed")
else:
with f:
print(f.read())
Lo llamo "programación optimista". La idea es que la mayoría de las veces las personas harán lo correcto, y los errores deberían ser pocos. Así que codifique primero para que suceda "lo correcto" y luego detecte los errores si no lo hacen.
Mi sensación es que si un usuario va a cometer errores, debe ser el que sufra las consecuencias del tiempo. Las personas que usan la herramienta de la manera correcta se aceleran.