goto

Chema Cortés py en ch3m4.org
Lun Ene 3 14:40:51 CET 2005


El Viernes, 31 de Diciembre de 2004 16:05, Amm-Python escribió:
> Lleváis varios días dándole vueltas a lo del "herético" goto. El comando
> maldito.

Veo que el tema da para mucho ;-)

> Hay un proyecto que permite usar el goto en python, espero no haber
> abierto "la Caja de Pandora".
> http://www.entrian.com/goto/
> Es interesante ya que no acepta saltos entre funciones y o módulos,
> saltar dentro de un bucle o de una excepción.
> Es decir; es un goto muy controlado.
>
> Una comparación simple:
> # Ejemplo: Salir de un bucle profundamente anidado:
> #1.- Con banderas.
> #2.- Con try
> #3.- Usando una funcion
> #4.- Con goto 8-O
>
> Visto lo visto: La simulación de gotos con Try es casi idéntica al uso
> del propio "goto". Por lo que pregunto:
> Es ortodoxo usar el comando try en estas situaciones ?
> En caso afirmativo: Sería lícito usar el módulo "goto" en lugar de try ?
> En caso contrario: Cuál es la solución ?

Parece forzado el uso del try..except, pero su uso puede estar justificado 
para salir "instantáneamente" de un bloque de ejecución. Para que quede mejor 
crearía una excepción "explícita" y añadiría una claúsula "else":

#2bis.- Con try

class LoopKilled(Exception):pass
try:
    for i in range(1, 10):
        print i
        for j in range(1, 20):
            print i, j
            for k in range(1, 30):
                print i, j, k
                if k == 3:
                    raise LoopKilled
except LoopKilled:
    print "Looping killedFinished with try\n"
else:
    print "Finished without exceptions\n"


En cuanto a los bucles "for", no me gusta salir por la fuerza. Si hay que 
cortarlos antes de tiempo, resulta más "ilustrativo" cambiarlos por bucles 
"while":

#1bis.- Con banderas (bucle while). 
flag=True
i,j,k=1,1,1
while flag and i<10:
    print i
    while flag and j<20:
        print i, j
        while flag and k<30:
            print i, j, k
            if k == 3:
                flag=False
            k+=1
        j+=1
    i+=1

print "Finished with flags\n"


Como "truco" final, es posible crear iteradores que integren condiciones. Para 
ésto se utiliza la ayuda de la función 'takewhile' del módulo 'itertools'. 
Refactorizando mucho quedaría algo así:

from itertools import takewhile

def iterador(n):
  def cond():
    return not getattr(iterador,"kill",False)
  return takewhile(cond,xrange(1,n))

for i in iterador(10):
  print i
  for j in iterador(20):
    print i,j
    for k in iterador(30):
      print i,j,k
      if k==3:
        iterator.kill=True



Estas dos últimas soluciones siguen siendo soluciones agotar la iteración, 
pero la salida sólo se producirá en la siguiente iteración. El único método 
capaz de garantizar la salida instantánea del bloque es una excepción.

En cuanto a si resulta lícito usar el módulo goto en lugar de las excepciones, 
este módulo tiene más pinta de ser una broma que algo que se pueda usar.
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: no disponible
Type: application/pgp-signature
Size: 189 bytes
Desc: no disponible
URL: <http://mail.python.org/pipermail/python-es/attachments/20050103/4d475ce3/attachment.pgp>
------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es