¿Hay una etiqueta / goto en Python?

¿Hay un goto o un equivalente en Python para poder saltar a una línea específica de código?

No, Python no admite tags y goto, si eso es lo que buscas. Es un lenguaje de progtwigción (altamente) estructurado.

Python te ofrece la posibilidad de hacer algunas de las cosas que podrías hacer con un goto utilizando funciones de primera clase. Por ejemplo:

 void somefunc(int a) { if (a == 1) goto label1; if (a == 2) goto label2; label1: ... label2: ... } 

Podría hacerse en python así:

 def func1(): ... def func2(): ... funcmap = {1 : func1, 2 : func2} def somefunc(a): funcmap[a]() #Ugly! But it works. 

Por supuesto, esa no es la mejor manera de sustituir goto. Pero sin saber exactamente lo que intentas hacer con el goto, es difícil dar consejos específicos.

@ ascobol :

Su mejor apuesta es encerrarla en una función o usar una excepción. Para la función:

 def loopfunc(): while 1: while 1: if condition: return 

Para la excepción:

 try: while 1: while 1: raise BreakoutException #Not a real exception, invent your own except BreakoutException: pass 

Usar excepciones para hacer cosas como esta puede parecer un poco incómodo si vienes de otro lenguaje de progtwigción. Pero diría que si no te gusta usar excepciones, Python no es el idioma para ti. 🙂

Recientemente escribí una función de decorador que permite goto a Python, así:

 from goto import with_goto @with_goto def range(start, stop): i = start result = [] label .begin if i == stop: goto .end result.append(i) i += 1 goto .begin label .end return result 

Aunque no estoy seguro de por qué a alguien le gustaría hacer algo así. Dicho esto, no soy muy serio al respecto. Pero me gustaría señalar que este tipo de progtwigción meta es realmente posible en Python, al menos en CPython y PyPy, y no solo haciendo un mal uso de la API del depurador como lo hizo ese otro tipo . Tienes que meterte con el bytecode sin embargo.

Encontré esto en el FAQ oficial de diseño e historia de python .

¿Por qué no hay goto?

Puede usar excepciones para proporcionar un “goto estructurado” que incluso funciona a través de llamadas a funciones. Muchos creen que las excepciones pueden emular convenientemente todos los usos razonables de las construcciones “ir” o “ir a” de C, Fortran y otros idiomas. Por ejemplo:

 class label(Exception): pass # declare a label try: ... if condition: raise label() # goto label ... except label: # where to goto pass ... 

Esto no te permite saltar al medio de un bucle, pero de todos modos generalmente se considera un abuso de goto. Utilizar con moderación.

Es muy bueno que esto se mencione incluso en las preguntas frecuentes oficiales, y que se proporcione una buena muestra de solución. Realmente me gusta python porque su comunidad está tratando incluso a goto esta manera;)

Para responder a la pregunta de @bobince usando la sugerencia de @bobince de los comentarios:

 for i in range(5000): for j in range(3000): if should_terminate_the_loop: break else: continue # no break encountered break 

La sangría para el bloque else es correcta. El código utiliza el modo “obscure else después de la syntax de Python. Ver ¿Por qué python usa ‘else’ después de los bucles for y while?

Se ha realizado una versión de trabajo: http://entrian.com/goto/ .

Nota: Se ofreció como una broma de April Fool. (trabajando aunque)

 # Example 1: Breaking out from a deeply nested loop: from goto import goto, label for i in range(1, 10): for j in range(1, 20): for k in range(1, 30): print i, j, k if k == 3: goto .end label .end print "Finished\n" 

Excusado es decir que. Sí, es gracioso, pero NO lo uses.

Las tags para break y continue se propusieron en PEP 3136 en 2007, pero se rechazaron. La sección de Motivación de la propuesta ilustra varios métodos comunes (si no son poco elegantes) para imitar la break etiquetada en Python.

Es técnicamente factible agregar una statement ‘goto’ como a python con algo de trabajo. Usaremos los módulos “dis” y “new”, ambos muy útiles para escanear y modificar el código de bytes de python.

La idea principal detrás de la implementación es marcar primero un bloque de código como el uso de declaraciones “goto” y “label”. Se utilizará un decorador especial “@goto” para marcar las funciones “goto”. Luego, escaneamos ese código en busca de estas dos declaraciones y aplicamos las modificaciones necesarias al código de byte subyacente. Todo esto sucede en el tiempo de comstackción del código fuente.

 import dis, new def goto(fn): """ A function decorator to add the goto command for a function. Specify labels like so: label .foo Goto labels like so: goto .foo Note: you can write a goto statement before the correspnding label statement """ labels = {} gotos = {} globalName = None index = 0 end = len(fn.func_code.co_code) i = 0 # scan through the byte codes to find the labels and gotos while i < end: op = ord(fn.func_code.co_code[i]) i += 1 name = dis.opname[op] if op > dis.HAVE_ARGUMENT: b1 = ord(fn.func_code.co_code[i]) b2 = ord(fn.func_code.co_code[i+1]) num = b2 * 256 + b1 if name == 'LOAD_GLOBAL': globalName = fn.func_code.co_names[num] index = i - 1 i += 2 continue if name == 'LOAD_ATTR': if globalName == 'label': labels[fn.func_code.co_names[num]] = index elif globalName == 'goto': gotos[fn.func_code.co_names[num]] = index name = None i += 2 # no-op the labels ilist = list(fn.func_code.co_code) for label,index in labels.items(): ilist[index:index+7] = [chr(dis.opmap['NOP'])]*7 # change gotos to jumps for label,index in gotos.items(): if label not in labels: raise Exception("Missing label: %s"%label) target = labels[label] + 7 # skip NOPs ilist[index] = chr(dis.opmap['JUMP_ABSOLUTE']) ilist[index + 1] = chr(target & 255) ilist[index + 2] = chr(target >> 8) # create new function from existing function c = fn.func_code newcode = new.code(c.co_argcount, c.co_nlocals, c.co_stacksize, c.co_flags, ''.join(ilist), c.co_consts, c.co_names, c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno, c.co_lnotab) newfn = new.function(newcode,fn.func_globals) return newfn if __name__ == '__main__': @goto def test1(): print 'Hello' goto .the_end print 'world' label .the_end print 'the end' test1() 

Espero que esto responda la pregunta.

Estaba buscando algo similar a

 for a in xrange(1,10): A_LOOP for b in xrange(1,5): for c in xrange(1,5): for d in xrange(1,5): # do some stuff if(condition(e)): goto B_LOOP; 

Así que mi enfoque fue usar un booleano para ayudar a salir de los bucles nesteds:

 for a in xrange(1,10): get_out = False for b in xrange(1,5): if(get_out): break for c in xrange(1,5): if(get_out): break for d in xrange(1,5): # do some stuff if(condition(e)): get_out = True break 

puede utilizar excepciones definidas por el usuario para emular goto

ejemplo:

 class goto1(Exception): pass class goto2(Exception): pass class goto3(Exception): pass def loop(): print 'start' num = input() try: if num<=0: raise goto1 elif num<=2: raise goto2 elif num<=4: raise goto3 elif num<=6: raise goto1 else: print 'end' return 0 except goto1 as e: print 'goto1' loop() except goto2 as e: print 'goto2' loop() except goto3 as e: print 'goto3' loop() 

Quería la misma respuesta y no quería usar goto . Así que utilicé el siguiente ejemplo (de learnpythonthehardway)

 def sample(): print "This room is full of gold how much do you want?" choice = raw_input("> ") how_much = int(choice) if "0" in choice or "1" in choice: check(how_much) else: print "Enter a number with 0 or 1" sample() def check(n): if n < 150: print "You are not greedy, you win" exit(0) else: print "You are nuts!" exit(0) 

Hay ahora ir

Creo que esto podría ser útil para lo que estás buscando.

Tengo mi propia manera de hacer gotos. Yo uso guiones de Python separados.

Si quiero hacer un bucle:

file1.py

 print("test test") execfile("file2.py") a = a + 1 

file2.py

 print(a) if a == 10: execfile("file3.py") else: execfile("file1.py") 

file3.py

 print(a + " equals 10") 

( NOTA: esta técnica solo funciona en las versiones de Python 2.x)

Para un Goto hacia adelante, puedes agregar:

 while True: if some condition: break #... extra code break # force code to exit. Needed at end of while loop #... continues here 

Sin embargo, esto solo es útil para escenarios simples (es decir, anidarlos podría meterte en un lío)

En lugar de un equivalente de Python Goto, uso la instrucción break de la siguiente manera para realizar pruebas rápidas de mi código. Esto supone que tiene base de código estructurado. La variable de prueba se inicializa al inicio de su función y simplemente muevo el bloque “If test: break” al final del bloque nested if-then o el bucle que quiero probar, modificando la variable de retorno al final del código para reflejar la variable de bloque o bucle que estoy probando.

 def x: test = True If y: # some code If test: break return something 

no hay una forma alternativa de implementar goto instrucción

 class id: def data1(self): name=[] age=[] n=1 while n>0: print("1. for enter data") print("2. update list") print("3. show data") print("choose what you want to do ?") ch=int(input("enter your choice")) if ch==1: n=int(input("how many elemet you want to enter=")) for i in range(n): name.append(input("NAME ")) age.append(int(input("age "))) elif ch==2: name.append(input("NAME ")) age.append(int(input("age "))) elif ch==3: try: if name==None: print("empty list") else: print("name \t age") for i in range(n): print(name[i]," \t ",age[i]) break except: print("list is empty") print("do want to continue y or n") ch1=input() if ch1=="y": n=n+1 else: print("name \t age") for i in range(n): print(name[i]," \t ",age[i]) n=-1 p1=id() p1.data1()