He visto algunas implementaciones interesantes de declaraciones de cambio / caso con dictos en el pasado que me llevaron a esta respuesta. Usando el ejemplo que ha proporcionado, obtendrá lo siguiente. (Es una locura using_complete_sentences_for_function_names
, por check_all_conditions
lo que cambia su nombre a status
. Ver (1))
def status(k = 'a', s = {'a':'b','b':'c','c':'d','d':None}) :
select = lambda next, test : test if test else next
d = {'a': lambda : select(s['a'], check_size() ),
'b': lambda : select(s['b'], check_color() ),
'c': lambda : select(s['c'], check_tone() ),
'd': lambda : select(s['d'], check_flavor())}
while k in d : k = d[k]()
return k
La función de selección elimina la necesidad de llamar cada check_FUNCTION
dos veces, es decir, evita check_FUNCTION() if check_FUNCTION() else next
agregar otra capa de función. Esto es útil para funciones de larga duración. Las lambdas en el dict retrasan la ejecución de sus valores hasta el ciclo while.
Como beneficio adicional, puede modificar el orden de ejecución e incluso omitir algunas de las pruebas alterando k
y, s
por ejemplo,k='c',s={'c':'b','b':None}
reducir el número de pruebas e invertir el orden de procesamiento original.
Los timeit
becarios podrían regatear el costo de agregar una o dos capas adicionales a la pila y el costo de la búsqueda de datos, pero parece más preocupado por la belleza del código.
Alternativamente, una implementación más simple podría ser la siguiente:
def status(k=check_size) :
select = lambda next, test : test if test else next
d = {check_size : lambda : select(check_color, check_size() ),
check_color : lambda : select(check_tone, check_color() ),
check_tone : lambda : select(check_flavor, check_tone() ),
check_flavor: lambda : select(None, check_flavor())}
while k in d : k = d[k]()
return k
- Quiero decir esto no en términos de pep8 sino en términos de usar una palabra descriptiva concisa en lugar de una oración. De acuerdo, el OP puede estar siguiendo alguna convención de codificación, trabajando una base de código existente o no importa términos breves en su base de código.
x and return x
es mejor queif x: return x
? Este último es mucho más legible y, por lo tanto, mantenible. No debe preocuparse demasiado por la cantidad de caracteres o líneas; la legibilidad cuenta. De todos modos, son exactamente el mismo número de caracteres que no son espacios en blanco, y si realmente debe hacerlo,if x: return x
funcionará bien en una sola línea.x
(en oposición abool(x)
), por lo que tal como está, creo que es seguro asumir que las funciones de OP pueden devolver cualquier cosa, y él quiere lo primero que sea verdadero.