¿Cuál es el principio EAFP en Python?


Respuestas:


216

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 tryy exceptdeclaraciones. 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.


34
Una mejora sería que otra ventaja es evitar las condiciones de carrera ... por ejemplo, simplemente intente abrir un archivo y, si lo obtiene, lo tendrá. En lugar de ver si puede obtenerlo , intente obtenerlo después y darse cuenta de que en el minúsculo período de tiempo entre el cheque y el intento de acceso, ya puede obtenerlo.
Jon Clements

23
Python también proporciona una forma de evitar ambos, si el controlador solo está asignando un valor predeterminado a xcuando la clave no existe: x = mydict.get('key')regresará Nonesi '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.defaultdictson cosas buenas para evitar el exceso de código también.
JAB

1
Creo que except KeyErroral igual que AttributeErrorson simples pero algunos de los peores ejemplos. Muchas veces me quedé atrapado depurando algo porque except AttributeErrorse 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
esquí

44
@ski Ese es un problema ligeramente diferente. Usted debe siempre mantener el bloque try lo mínimo posible para evitar la captura la excepción equivocado. También tenga en cuenta que generalmente no prefiero el estilo EAFP. Solo estoy respondiendo la pregunta aquí, y afirmo que algunas personas lo prefieren. De acuerdo con cada caso, decido qué código me parece más legible.
Sven Marnach

1
Pensé que valdría la pena mencionar que Grace Hopper es probablemente la fuente de esta frase, con su cita: "Atrévete y hazlo. Es más fácil pedir perdón que pedir permiso" (no se limita a la programación).
Fabien Snauwaert

9

Trataré de explicarlo con otro ejemplo.

Aquí estamos intentando acceder al archivo e imprimir el contenido en la consola.

LBYL - Mira antes de saltar:

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 elseparte. 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")

EAFP: más fácil pedir perdón que permiso:

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())

No estoy seguro de que sea correcto describir esto como una condición de carrera. O el archivo es accesible o no.
ds4940

3
@ ds4940 Es la condición de carrera si la accesibilidad del archivo cambia entre las líneas 6 y 7, es decir, entre verificar si el archivo es accesible y abrirlo.
Markus von Broady

@MarkusvonBroady estuvo de acuerdo, editó la respuesta para proporcionar un ejemplo del otro participante en la condición de la carrera.
ds4940

6

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.