El equivalente de un GOTO en python [duplicado]


Esta pregunta ya tiene una respuesta aquí:

Soy autodidacta python 2.7. Tengo algo de experiencia en el uso de LOTE, que tiene una declaración GOTO. ¿Cómo hago eso en Python? Por ejemplo, supongamos que quiero saltar de la línea 5 a la línea 18.

Me doy cuenta de que ha habido preguntas anteriores en cuanto a este tema, pero no los he encontrado suficientemente informativos o, son demasiado de alto nivel en python para mi comprensión actual.

 31
Author: csgillespie, 2013-09-18

6 answers

Gotos son universalmente vilipendiados en ciencias de la computación y la programación, ya que conducen a un código muy desestructurado.

Python (como casi todos los lenguajes de programación actuales) soportaprogramación estructurada que controla el flujo usando if/then/else, loop y subrutinas.

La clave para pensar de una manera estructurada es entender cómo y por qué se está ramificando en el código.

Por ejemplo, supongamos que Python tenía una instrucción goto y la correspondiente label estremecerse. Mira el siguiente código. En él si un número es mayor o igual a 0 se imprime si

number = input()
if number < 0: goto negative
if number % 2 == 0:
   print "even"
else:
   print "odd"
goto end
label: negative
print "negative"
label: end
print "all done"

Si queremos saber cuándo se ejecuta una pieza de código, necesitamos rastrear cuidadosamente en el programa y examinar cómo se llegó a una etiqueta, que es algo que realmente no se puede hacer.

Por ejemplo, podemos reescribir lo anterior como:

number = input()
goto check

label: negative
print "negative"
goto end

label: check
if number < 0: goto negative
if number % 2 == 0:
   print "even"
else:
   print "odd"
goto end

label: end
print "all done"

Aquí, hay dos maneras posibles de llegar al "final", y no podemos saber cuál fue elegido. Como los programas se hacen grandes este tipo de problema empeora y resulta en spaghetti code

En comparación, a continuación se muestra cómo escribiría este programa en Python:

number = input()
if number >= 0:
   if number % 2 == 0:
       print "even"
   else:
       print "odd"
else:
   print "negative"
print "all done"

Puedo mirar una línea de código en particular, y saber bajo qué condiciones se cumple rastreando el árbol de if/then/else bloques en los que se encuentra. Por ejemplo, sé que la línea print "odd" se ejecutará cuando un ((number >= 0) == True) and ((number % 2 == 0) == False).

 46
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-18 06:36:28

Perdóname - no pude resistir ;-)

def goto(linenum):
    global line
    line = linenum

line = 1
while True:
    if line == 1:
        response = raw_input("yes or no? ")
        if response == "yes":
            goto(2)
        elif response == "no":
            goto(3)
        else:
            goto(100)
    elif line == 2:
        print "Thank you for the yes!"
        goto(20)
    elif line == 3:
        print "Thank you for the no!"
        goto(20)
    elif line == 20:
        break
    elif line == 100:
        print "You're annoying me - answer the question!"
        goto(1)
 43
Author: Tim Peters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-18 03:45:38

Estoy totalmente de acuerdo en que goto es una codificación pobre, pero nadie ha respondido realmente a la pregunta. Hay de hecho un módulo goto para Python (aunque fue lanzado como una broma de April fool y no se recomienda su uso, funciona).

 31
Author: scohe001,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-20 17:50:02

No hay instrucción goto en el lenguaje de programación Python. Tendrás que escribir tu código de una manera estructurada... Pero realmente, ¿por qué quieres usar un goto? eso ha sido considerado dañino durante décadas, y cualquier programa que se te ocurra se puede escribir sin usar goto.

Por supuesto, hay algunos casos donde un salto incondicional podría ser útil , pero nunca es obligatorio , siempre existirá una semántica solución equivalente, estructurada que no necesita goto.

 7
Author: Óscar López,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:53

Descargo de responsabilidad: He estado expuesto a una cantidad significativa de F77

El equivalente moderno de goto (discutible, solo mi opinión, etc.) es el manejo explícito de excepciones:

Editado para resaltar mejor la reutilización de código.

Pretenda pseudocódigo en un falso lenguaje similar a python con goto:

def myfunc1(x)
    if x == 0:
        goto LABEL1
    return 1/x

def myfunc2(z)
    if z == 0:
        goto LABEL1
    return 1/z

myfunc1(0) 
myfunc2(0)

:LABEL1
print 'Cannot divide by zero'.

Comparado con python:

def myfunc1(x):
    return 1/x

def myfunc2(y):
    return 1/y


try:
    myfunc1(0)
    myfunc2(0)
except ZeroDivisionError:
    print 'Cannot divide by zero'

Las excepciones con nombre explícito son significativamente una mejor manera de tratar con el condicional no lineal ramificación.

 6
Author: Caleb Hattingh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-18 03:57:55
answer = None
while True:
    answer = raw_input("Do you like pie?")
    if answer in ("yes", "no"): break
    print "That is not a yes or a no"

Te daría lo que quieres sin una declaración goto.

 3
Author: Paul Becotte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-18 04:30:03