Estoy tratando de imitar el comportamiento de las funciones incorporadas (como getattr
) que permiten al usuario especificar un valor de retorno "predeterminado". Mi intento inicial era hacer estopython - devolviendo un valor predeterminado
def myfunc(foo, default=None):
# do stuff
if (default is not None):
return default
raise SomeException()
El problema es que si los usuarios quiere None
ser su valor de retorno, esta función en lugar podría lanzar una excepción. segundo intento:
def myfunc(foo, **kwargs):
# do stuff
if ('default' in kwargs):
return kwargs['default']
raise SomeException()
Esto aborda la cuestión antedicha y permite al usuario especificar cualquier valor arbitrario, pero introduce una molestia en el que el usuario siempre debe especificar default=bar
en su función llama; no pueden simplemente proporcionar bar
al final. Del mismo modo, podría usarse *args
, pero evita que los usuarios usen default=bar
si prefieren esa sintaxis.
La combinación de *args
y **kwargs
proporciona una solución práctica, pero parece que esto va a hacer un gran esfuerzo. También potencialmente máscaras llamadas a funciones inadecuadas (por ejemplo bar = myfunc(foo, baz, default=qux)
)
def myfunc(foo, *args, **kwargs):
# do stuff
if (len(args) == 1):
return args[0]
if ('default' in kwargs):
return kwargs['default']
raise SomeException()
¿Existe una solución más simple? (Python 3.2 si lo que importa)
que es mucho más simple, gracias! – Steve
¿Hay alguna forma de evitar que la gente pase centinela? –
@hayden: por supuesto que no, esto es python. Generalmente lo llamas '_sentinel' o similar para marcarlo como privado, pero eso no impide que las almas emprendedoras rompan todo importándolo de todos modos. No tiene sentido hacerlo, por supuesto. –