Qual é o princípio do EAFP no Python?

Respostas:

216

No glossário :

Mais fácil pedir perdão do que permissão. Esse estilo comum de codificação Python pressupõe a existência de chaves ou atributos válidos e captura exceções se a suposição for falsa. Este estilo limpo e rápido é caracterizado pela presença de muitos trye exceptdeclarações. A técnica contrasta com o estilo LBYL comum a muitos outros idiomas, como C.

Um exemplo seria uma tentativa de acessar uma chave de dicionário.

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

A versão LBYL deve procurar a chave dentro do dicionário duas vezes e também pode ser considerada um pouco menos legível.

Sven Marnach
fonte
34
Uma melhoria seria que outra vantagem é evitar condições de corrida ... por exemplo, tente abrir um arquivo e, se você o conseguir, você o terá. Em vez de ver se você pode obtê-lo , tente obtê-lo posteriormente e perceba que no minúsculo período de tempo entre a verificação e a tentativa de acesso, você pode obtê-lo por mais tempo.
Jon Clements
23
O Python também fornece uma maneira de evitar os dois, se o manipulador está apenas atribuindo um valor padrão para xquando a chave não existe: x = mydict.get('key')retornará Nonese 'key'não estiver my_dict; você também pode fazer .get('key', <something>)e, em seguida, x será atribuído a algo assim se a chave não estiver no dicionário. dict.setdefault()e collections.defaultdictsão boas coisas para evitar o excesso de código também.
JAB
1
Eu acho except KeyErrorque AttributeErrorsão simples, mas são alguns dos piores exemplos. Muitas vezes eu estava preso a depurar alguma coisa porque except AttributeErrorfoi colocado no lugar errado, o que acabou pegando um erro de atributo errado gerado mais profundamente na cadeia. Melhores exemplos que eu acho que são: try: open() ... except: IOError. Outry: parseLine() ... except ParseError
Ski
4
@ski Esse é um problema um pouco diferente. Você deve sempre manter o bloco try o mínimo possível para evitar a exceção errada. Observe também que geralmente não prefiro o estilo EAFP. Estou apenas respondendo à pergunta aqui e afirmo que algumas pessoas preferem. Declaro, caso a caso, qual código parece mais legível para mim.
Sven Marnach
1
Eu pensei que valeria a pena mencionar que Grace Hopper é provavelmente a fonte dessa frase, com sua citação: "Dare and Do. É mais fácil pedir perdão do que obter permissão" (não restrito à programação).
Fabien Snauwaert
9

Vou tentar explicar com outro exemplo.

Aqui estamos tentando acessar o arquivo e imprimir o conteúdo no console.

LBYL - Olhe antes de pular:

Podemos querer verificar se podemos acessar o arquivo e, se pudermos, abriremos e imprimiremos o conteúdo. Se não pudermos acessar o arquivo, acessaremos a elseparte. A razão pela qual essa é uma condição de corrida é porque primeiro fazemos uma verificação de acesso. Quando chegamos, with open(my_file) as f:talvez não possamos mais acessá-lo devido a alguns problemas de permissão (por exemplo, outro processo ganha um bloqueio exclusivo de arquivo). Esse código provavelmente causará um erro e não poderemos capturá-lo porque pensamos que poderíamos acessar o arquivo.

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 - Mais fácil pedir perdão do que permissão:

Neste exemplo, estamos apenas tentando abrir o arquivo e, se não podemos abri-lo, lançará um IOError. Se pudermos, abriremos o arquivo e imprimiremos o conteúdo. Então, em vez de perguntar algo, estamos tentando fazer isso. Se funcionar, ótimo! Caso contrário, capturamos o erro e o tratamos.

# # No race condition
try:
    f = open(my_file)
except IOError as e:
    print("File can't be accessed")
else:
    with f:
        print(f.read())
Apoorv Patne
fonte
Não sei se é correto descrever isso como uma condição de corrida. O arquivo está acessível ou não.
ds4940
3
@ ds4940 É a condição de corrida se a acessibilidade do arquivo mudar entre as linhas 6 e 7, ou seja, verificar se o arquivo está acessível e abri-lo.
Markus von Broady
O @MarkusvonBroady concordou, editou a resposta para fornecer um exemplo do outro participante na condição de corrida.
ds4940 10/10/19
6

Eu chamo de "programação otimista". A ideia é que na maioria das vezes as pessoas façam a coisa certa, e os erros devem ser poucos. Portanto, primeiro codifique para que a "coisa certa" aconteça e, em seguida, identifique os erros, caso contrário.

Meu sentimento é que, se um usuário cometer erros, ele deve sofrer as conseqüências do tempo. As pessoas que usam a ferramenta da maneira certa são aceleradas.

Engenheiro
fonte