¿La siguiente función de Python es una buena práctica?

No estoy seguro si estoy en lo cierto aquí, así que tómalo con un poco de sal.

Las excepciones son generalmente costosas ya que se requieren estados para guardar en la pila que luego se extraen de ella. A continuación se muestra una demostración:

Definamos una función func1 similar a la suya y desmontemos su bytecode.

def func1 ():
tv = str (valor aleatorio ())
tratar:
si get_values ​​(tv):
func1 ()
excepto:
volver tv

A continuación se muestra el resultado de dis.dis (func1)

2 0 LOAD_GLOBAL 0 (str)
3 LOAD_GLOBAL 1 (valor aleatorio)
6 CALL_FUNCTION 0
9 CALL_FUNCTION 1
12 STORE_FAST 0 (tv)

3 15 SETUP_EXCEPT 26 (a 44)

4 18 LOAD_GLOBAL 2 (get_values)
21 LOAD_FAST 0 (tv)
24 CALL_FUNCTION 1
27 POP_JUMP_IF_FALSE 40

5 30 LOAD_GLOBAL 3 (func1)
33 CALL_FUNCTION 0
36 POP_TOP
37 JUMP_FORWARD 0 (a 40)
>> 40 POP_BLOCK
41 JUMP_FORWARD 8 (a 52)

6 >> 44 POP_TOP
45 POP_TOP
46 POP_TOP

7 47 LOAD_FAST 0 (tv)
50 RETURN_VALUE
51 END_FINALLY
>> 52 LOAD_CONST 0 (Ninguno)
55 RETURN_VALUE

Ahora definamos otra func1 usando loop

def func1 ():
tv = str (valor aleatorio ())
mientras get_value (tv):
func1 ()
más:
volver tv

2 0 LOAD_GLOBAL 0 (str)
3 LOAD_GLOBAL 1 (valor aleatorio)
6 CALL_FUNCTION 0
9 CALL_FUNCTION 1
12 STORE_FAST 0 (tv)

3 15 SETUP_LOOP 27 (a 45)
>> 18 LOAD_GLOBAL 2 (obtener_valor)
21 LOAD_FAST 0 (tv)
24 CALL_FUNCTION 1
27 POP_JUMP_IF_FALSE 40

4 30 LOAD_GLOBAL 3 (func1)
33 CALL_FUNCTION 0
36 POP_TOP
37 JUMP_ABSOLUTE 18
>> 40 POP_BLOCK

6 41 LOAD_FAST 0 (tv)
44 RETURN_VALUE
>> 45 LOAD_CONST 0 (Ninguno)
48 RETURN_VALUE

Podemos ver que el intérprete está realizando más pasos de operación en el primer caso, lo que claramente no es la mejor manera de hacerlo.

Avíseme en caso de que parezca que me falta algo,

No estoy seguro si esta es una buena práctica de Python. Pero esta no es una buena práctica de programación. La misma función se puede escribir simplemente usando un bucle. Si no es posible un bucle simple, entonces la recursión puede usarse para escribir código elegante.

El mejor ejemplo para este caso es el triángulo de Pascal, donde el bucle puede resultar en un código simple pero no bueno para leer. Usando la recursión podemos tener un código elegante y legible.