Eu estava pensando sobre as melhores práticas para indicar combinações de argumentos inválidos em Python. Eu me deparei com algumas situações em que você tem uma função assim:
def import_to_orm(name, save=False, recurse=False):
"""
:param name: Name of some external entity to import.
:param save: Save the ORM object before returning.
:param recurse: Attempt to import associated objects as well. Because you
need the original object to have a key to relate to, save must be
`True` for recurse to be `True`.
:raise BadValueError: If `recurse and not save`.
:return: The ORM object.
"""
pass
O único incômodo com isso é que cada pacote tem o seu, geralmente um pouco diferente BadValueError
. Eu sei que em Java existe java.lang.IllegalArgumentException
- é bem entendido que todos estarão criando seus próprios BadValueError
s em Python ou existe outro método preferido?
math.sqrt(-1)
, é um erro de programação que precisa ser corrigido de qualquer maneira.ValueError
não se destina a ser capturado na execução normal do programa ou do qual derivariaRuntimeError
.Eu herdaria de
ValueError
Às vezes, é melhor criar suas próprias exceções, mas herdar de uma embutida, o mais próximo possível do que você deseja.
Se você precisar capturar esse erro específico, é útil ter um nome.
fonte
Eu acho que a melhor maneira de lidar com isso é a maneira como o próprio python lida com isso. Python gera um TypeError. Por exemplo:
Nosso desenvolvedor júnior acabou de encontrar esta página em uma pesquisa no google por "argumentos errados de exceção de python" e estou surpreso que a resposta óbvia (para mim) nunca tenha sido sugerida na década desde que essa pergunta foi feita.
fonte
int('a')
). fontesum()
sem argumentos, que é umTypeError
, mas o OP estava preocupado com combinações "ilegais" de valores de argumento quando os tipos de argumento estão corretos. Nesse caso, ambossave
erecurse
são bools, mas serecurse
for,True
entãosave
não deve serFalse
. Isto é umValueError
. Concordo que alguma interpretação do título da pergunta seria respondida porTypeError
, mas não para o exemplo apresentado.Acabei de ver o componente
ValueError
usado nessa situação.fonte
Depende de qual é o problema com os argumentos.
Se o argumento tiver o tipo errado, aumente um TypeError. Por exemplo, quando você obtém uma string em vez de um desses booleanos.
Note, no entanto, que no Python raramente fazemos verificações como essa. Se o argumento for realmente inválido, alguma função mais profunda provavelmente fará a reclamação por nós. E se verificarmos apenas o valor booleano, talvez algum usuário de código mais tarde a alimente com uma string sabendo que as strings não vazias são sempre True. Isso pode lhe salvar um elenco.
Se os argumentos tiverem valores inválidos, aumente ValueError. Isso parece mais apropriado no seu caso:
Ou, nesse caso específico, ter um valor True de recurse implica um valor True de save. Como eu consideraria isso uma recuperação de um erro, você também pode reclamar no log.
fonte
Eu não sei se concordo com a herança de
ValueError
- minha interpretação da documentação é queValueError
é única deveria ser levantada por builtins ... herdar a partir dele ou elevando-se parece incorreta.- documentação ValueError
fonte
ValueError
para esse tipo de coisa, então acho que você está tentando ler muito na documentação.Concorde com a sugestão de Markus de lançar sua própria exceção, mas o texto da exceção deve esclarecer que o problema está na lista de argumentos, não nos valores individuais dos argumentos. Eu proporia:
Usado quando faltam argumentos de palavra-chave necessários para a chamada específica ou valores de argumento individualmente válidos, mas inconsistentes entre si.
ValueError
ainda estaria certo quando um argumento específico é do tipo certo, mas está fora do intervalo.Isso não deveria ser uma exceção padrão no Python?
Em geral, eu gostaria que o estilo Python fosse um pouco mais preciso ao distinguir entradas ruins de uma função (falha do chamador) e resultados ruins dentro da função (minha falha). Portanto, também pode haver um BadArgumentError para distinguir erros de valor nos argumentos dos erros de valor nos locais.
fonte
KeyError
para a palavra-chave não encontrada (já que uma palavra-chave explícita ausente é semanticamente idêntica a um**kwargs
ditado que está faltando essa chave).