Is there a label/goto in Python?

Is there a goto or any equivalent in Python to be able to jump to a specific line of code?

5

22 Answers

No, Python does not support labels and goto. It's a (highly) structured programming language.

0

Python offers you the ability to do some of the things you could do with a goto using first class functions. For example:

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

Could be done in Python like this:

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

Granted, that isn't the best way to substitute for goto. But without knowing exactly what you're trying to do with the goto, it's hard to give specific advice.

@ascobol:

Your best bet is to either enclose it in a function or use an exception. For the function:

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

For the exception:

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

Using exceptions to do stuff like this may feel a bit awkward if you come from another programming language. But I would argue that if you dislike using exceptions, Python isn't the language for you. :-)

3

I recently wrote a function decorator that enables goto in Python, just like that:

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

I'm not sure why one would like to do something like that though. That said, I'm not too serious about it. But I'd like to point out that this kind of meta programming is actual possible in Python, at least in CPython and PyPy, and not only by misusing the debugger API as that other guy did. You have to mess with the bytecode though.

5

I found this in the official python Design and History FAQ.

Why is there no goto?

You can use exceptions to provide a “structured goto” that even works across function calls. Many feel that exceptions can conveniently emulate all reasonable uses of the “go” or “goto” constructs of C, Fortran, and other languages. For example:

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

This doesn’t allow you to jump into the middle of a loop, but that’s usually considered an abuse of goto anyway. Use sparingly.

It's very nice that this is even mentioned in the official FAQ, and that a nice solution sample is provided. I really like python because its community is treating even goto like this ;)

5

To answer the @ascobol's question using @bobince's suggestion from the comments:

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

The indent for the else block is correct. The code uses obscure else after a loop Python syntax. See Why does python use 'else' after for and while loops?

8

A working version has been made: .

Note: It was offered as an April Fool's joke. (working though)

# 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"

Needless to say. Yes its funny, but DONT use it.

2

It is technically feasible to add a 'goto' like statement to python with some work. We will use the "dis" and "new" modules, both very useful for scanning and modifying python byte code.

The main idea behind the implementation is to first mark a block of code as using "goto" and "label" statements. A special "@goto" decorator will be used for the purpose of marking "goto" functions. Afterwards we scan that code for these two statements and apply the necessary modifications to the underlying byte code. This all happens at source code compile time.

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()

Hope this answers the question.

1

Python 2 & 3

pip3 install goto-statement

Tested on Python 2.6 through 3.6 and PyPy.

Link: goto-statement


foo.py

from goto import with_goto
@with_goto
def bar(): label .bar_begin ... goto .bar_begin
0

Labels for break and continue were proposed in PEP 3136 back in 2007, but it was rejected. The Motivation section of the proposal illustrates several common (if inelegant) methods for imitating labeled break in Python.

you can use User-defined Exceptions to emulate goto

example:

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()
2

I was looking for some thing similar to

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;

So my approach was to use a boolean to help breaking out from the nested for loops:

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

Though there isn't any code equivalent to goto/label in Python, you could still get such functionality of goto/label using loops.

Lets take a code sample shown below where goto/label can be used in a arbitrary language other than python.

String str1 = 'BACK'
label1: print('Hello, this program contains goto code\n') print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code') str1 = input()
if str1 == 'BACK' { GoTo label1 }
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

Now the same functionality of the above code sample can be achieved in python by using a while loop as shown below.

str1 = 'BACK'
while str1 == 'BACK': print('Hello, this is a python program containing python equivalent code for goto code\n') print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code') str1 = input()
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

You can achieve it using nested methods inside python

def func1(): print("inside func1") def inline(): print("im inside") inline()
func1()

There is now. goto

I think this might be useful for what you are looking for.

When implementing "goto", one must first ask what a goto is. While it may seem obvious, most people don't think about how goto relates to function stacks.

If you perform a "goto" inside a function, you are, in effect, abandoning the function call stack. This is considered bad practice, because function stacks are designed with the expectation that you will continue where you left off, after delegating an intermediate task. This is why gotos are used for exceptions, and exceptions can be used to emulate goto, which i will explain.

Finite state machines are probably the best use case for goto, which most of the time are implemented in a kludgy way with loops and switch statements, but I believe that "top level" gotos, are the cleanest, most semantic way to implement finite state machines. In this case, you want to make sure, if you have more variables, they are globals, and don't require encapsulation. Make sure you first model your variable state space(which may be different from execution state, ie the finite state machine).

I believe there are legitimate design reasons to use goto, exception handling being the special case where mixing goto with functions makes sense. However, in most cases, you want to restrict yourself to "top level" goto, so you never call goto within a function, but only within a global scope.

The easiest way to emulate top level goto in modern languages, is to realize that top-level gotos, simply require global variables and an empty call stack. So to keep the call stack empty, you return whenever you call a new function. Here's an example to print the first n fibonacci numbers:

a = 0
b = 1
n = 100
def A(): global a, b a = a + b n -= 1 print(a) return B() if n > 0 else 0
def B(): global a, b b = a + b n -= 1 print(b) return A() if n > 0 else 0
A()

While this example may be more verbose than loop implementations, it is also much more powerful and flexible, and requires no special cases. It lets you have a full finite state machine. You could also modify this with a goto runner.

def goto(target): while(target) target = target()
def A(): global a, b a = a + b print(a) return B
def B(): global a, b b = a + b print(b) return A
goto(A)

To enforce the "return" part, you could write a goto function that simply throws an exception when finished.

def goto(target): target() throw ArgumentError("goto finished.")
def A(): global a, b a = a + b print(a) goto(B)
def B() global a, b b = a + b print(b) goto(A)
goto(A)

So you see, a lot of this is overthinking, and a helper function that calls a function and then throws an error is all you need. You could further wrap it in a "start" function, so the error gets caught, but I don't think that's strictly necessary. While some of these implementations may use up your call stack, the first runner example keeps it empty, and if compilers can do tail call optimization, that helps as well.

1

I wanted the same answer and I didnt want to use goto. So I used the following example (from 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)

I have my own way of doing gotos. I use separate python scripts.

If I want to loop:

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")

(NOTE: This technique only works on Python 2.x versions)

For a forward Goto, you could just add:

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

This only helps for simple scenarios though (i.e. nesting these would get you into a mess)

In lieu of a python goto equivalent I use the break statement in the following fashion for quick tests of my code. This assumes you have structured code base. The test variable is initialized at the start of your function and I just move the "If test: break" block to the end of the nested if-then block or loop I want to test, modifying the return variable at the end of the code to reflect the block or loop variable I'm testing.

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

no there is an alternative way to implement goto statement

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() 

I think while loop is alternate for the "goto_Statement". Because after 3.6 goto loop is not working anymore. I also write an example of the while loop.

str1 = "stop"
while str1 == "back": var1 = int(input(" Enter Ist Number: ")) var2 = int(input(" Enter 2nd Number: ")) var3 = print(""" What is your next operation For Addition Press And Enter : 'A' For Muliplt Press And Enter : 'M' For Division Press And Enter : 'D' For Subtaction Press And Enter : 'S' """) var4 = str(input("For operation press any number : ")) if(var1 == 45) and (var2 == 3): print("555") elif(var1 == 56) and (var2 == 9): print("77") elif(var1 == 56) and (var2 == 6): print("4") else: if(var4 == "A" or "a"): print(var1 + var2) if(var4 == "M" or "m"): print(var1 * var2) if(var4 == "D" or "d"): print(var1 / var2) if(var4 == "S" or "s"): print(var1 - var2) print("if you want to continue then type 'stop'") str1 = input()
print("Strt again") 

I solved this problem with functions. Only thing I did was change labels with functions. Here is a very basic code:

def goto_holiday(): #label: holiday print("I went to holiday :)")
def goto_work(): #label: work print("I went to work")
salary=5000
if salary>6000: goto_holiday()
else: goto_work()

You Might Also Like