Me preguntaba sobre las mejores prácticas para indicar combinaciones de argumentos no válidos en Python. Me he encontrado con algunas situaciones en las que tienes una función como esta:
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
La única molestia con esto es que cada paquete tiene el suyo, generalmente ligeramente diferente BadValueError
. Sé que en Java existe java.lang.IllegalArgumentException
, ¿se entiende bien que todos crearán sus propios BadValueError
s en Python o hay otro método preferido?
math.sqrt(-1)
, ese es un error de programación que debe ser reparado de todos modos.ValueError
no está destinado a quedar atrapado en la ejecución normal del programa o derivaría deRuntimeError
.Yo heredaría de
ValueError
A veces es mejor crear sus propias excepciones, pero heredar de uno incorporado, que es lo más parecido posible a lo que desea.
Si necesita detectar ese error específico, es útil tener un nombre.
fuente
Creo que la mejor manera de manejar esto es la forma en que Python lo maneja. Python plantea un TypeError. Por ejemplo:
Nuestro desarrollador junior acaba de encontrar esta página en una búsqueda en Google de "argumentos erróneos de excepción de Python" y me sorprende que la respuesta obvia (para mí) nunca se sugirió en la década desde que se hizo esta pregunta.
fuente
int('a')
). fuentesum()
sin argumentos, que es unTypeError
, pero el OP estaba preocupado con combinaciones "ilegales" de valores de argumento cuando los tipos de argumento son correctos. En este caso, tantosave
yrecurse
son Bools, pero sirecurse
esTrue
entoncessave
no debería serFalse
. Se trata de unaValueError
. Estoy de acuerdo en que alguna interpretación del título de la pregunta sería respondida porTypeError
, pero no por el ejemplo que se presenta.Sobre todo acabo de ver el builtin
ValueError
utilizado en esta situación.fuente
Depende de cuál sea el problema con los argumentos.
Si el argumento tiene el tipo incorrecto, genere un TypeError. Por ejemplo, cuando obtienes una cadena en lugar de uno de esos booleanos.
Sin embargo, tenga en cuenta que en Python rara vez hacemos verificaciones como esta. Si el argumento realmente no es válido, alguna función más profunda probablemente se quejará por nosotros. Y si solo verificamos el valor booleano, tal vez algún usuario de código luego lo alimente con una cadena sabiendo que las cadenas no vacías son siempre verdaderas. Podría ahorrarle un yeso.
Si los argumentos tienen valores no válidos, aumente ValueError. Esto parece más apropiado en su caso:
O en este caso específico, tener un valor Verdadero de recurrencia implica un valor Verdadero de guardar. Como consideraría esto una recuperación de un error, es posible que también desee quejarse en el registro.
fuente
No estoy seguro estoy de acuerdo con la herencia de
ValueError
- mi interpretación de la documentación es queValueError
se sólo se supone para ser criados por órdenes internas ... heredando de o elevándola a sí mismo parece incorrecta.- Documentación de ValueError
fuente
ValueError
para este tipo de cosas, así que creo que estás intentando leer demasiado en la documentación.De acuerdo con la sugerencia de Markus de lanzar su propia excepción, pero el texto de la excepción debería aclarar que el problema está en la lista de argumentos, no en los valores de los argumentos individuales. Yo propondría:
Se usa cuando faltan argumentos de palabras clave que fueron necesarios para la llamada específica, o los valores de argumento son válidos individualmente pero inconsistentes entre sí.
ValueError
seguiría siendo correcto cuando un argumento específico es del tipo correcto pero está fuera de rango.¿No debería ser esta una excepción estándar en Python?
En general, me gustaría que el estilo de Python sea un poco más preciso al distinguir las entradas incorrectas de una función (culpa del llamante) de los malos resultados dentro de la función (mi culpa). Por lo tanto, también puede haber un BadArgumentError para distinguir los errores de valor en los argumentos de los errores de valor en los locales.
fuente
KeyError
para la palabra clave no encontrada (ya que una palabra clave explícita que falta es semánticamente idéntica a un**kwargs
dict que falta esa clave).