54

I am self teaching myself python 2.7. I have some experience in using BATCH, which has a GOTO statement. How do I do that in python? For example, suppose I want to jump from line 5 to line 18.

I realize there have been previous questions regarding this topic, but I have not found them sufficiently informative or, are too high level in python for my current understanding.

csgillespie
  • 59,189
  • 14
  • 150
  • 185
Calder Hutchins
  • 755
  • 1
  • 6
  • 10
  • 1
    @kojiro Please read the whole topic. – Calder Hutchins Sep 18 '13 at 03:28
  • "One of thme mentioned a function, but i don't see how they would work." Understand how functions work, then you will see that you don't need `goto`. – Akavall Sep 18 '13 at 03:28
  • ok, I'll go do that Akavall – Calder Hutchins Sep 18 '13 at 03:30
  • 5
    Random: If you really do want to use a goto, somebody actually wrote [a working version](http://entrian.com/goto/) as part of an April Fool's joke in 2004. By no means do I recommend actually using it, but I thought I'd link it for amusement's sake. – Michael0x2a Sep 18 '13 at 03:51
  • I think whatever is the case, You must handle it by using while loop. – shubham12511 Apr 24 '17 at 12:50
  • in some cases exceptions can be used to implement goto-like behavior if id none of the other structural constructs can do what you want. – Jasen Feb 28 '18 at 22:02
  • Answer available in https://stackoverflow.com/questions/438844/is-there-a-label-goto-in-python/49052717#49052717. A failure handling in a function can be handled well with only goto statement. – rashok Mar 01 '18 at 15:12

6 Answers6

76

Forgive me - I couldn't resist ;-)

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)
Tim Peters
  • 67,464
  • 13
  • 126
  • 132
66

Gotos are universally reviled in computer science and programming as they lead to very unstructured code.

Python (like almost every programming language today) supports structured programming which controls flow using if/then/else, loop and subroutines.

The key to thinking in a structured way is to understand how and why you are branching on code.

For example, lets pretend Python had a goto and corresponding label statement shudder. Look at the following code. In it if a number is greater than or equal to 0 we print if it

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"

If we want to know when a piece of code is executed, we need to carefully traceback in the program, and examine how a label was arrived at - which is something that can't really be done.

For example, we can rewrite the above as:

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"

Here, there are two possible ways to arrive at the "end", and we can't know which one was chosen. As programs get large this kind of problem gets worse and results in spaghetti code

In comparison, below is how you would write this program in Python:

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

I can look at a particular line of code, and know under what conditions it is met by tracing back the tree of if/then/else blocks it is in. For example, I know that the line print "odd" will be run when a ((number >= 0) == True) and ((number % 2 == 0) == False).

  • 2
    +1, Your explanation was great, and all of the code looks good, but as the scripts get bigger and bigger, you may not be able to deal with a negative in a single line. if/else begins piling up with indents off the screen. It may be better then if in this example you take the input, call `check()`, and in `check()`, call `negative()` if we've found the number to be negative. Furthermore, this would show how easy it is to take `label`s and go straight to functions (which our OP doesn't seem to entirely grasp) – scohe001 Sep 18 '13 at 03:43
  • @CalderHutchins On face value `goto`s seem harmless and straight forward enough to new programmers - "Goto this place and do stuff". A lot of the time the reasons for why get lost in the mysts of time, but the rationales for structured programming still exist. –  Sep 18 '13 at 03:44
  • I'm only on my 3rd day learning python, give me a break ;) – Calder Hutchins Sep 18 '13 at 03:44
  • @Josh If your code is indented off the screen thats indicative of the [arrow anti-pattern](http://c2.com/cgi/wiki?ArrowAntiPattern). Its not an argument against structured programming, just an argument against poorly thought out programs. –  Sep 18 '13 at 03:46
  • 1
    @LegoStormtroopr I understand, that's why I'm trying to tell you to teach the OP about using functions to avoid that now in a simple example like this before you send another one of *those* programmers out into the fray (as I said before, he doesn't seem to have very much of a grasp on functions) – scohe001 Sep 18 '13 at 03:49
  • @CalderHutchins Don't think my comment "On the face value..." was an insult or directed at you. More an explanation for others as to why new programmers ask about `goto`s. They do seem intuitive and in small programs are. The issues with `goto`s don't come up until thousands of lines in, a shortcut here, a shortcut there, and then an unmaintainable nightmare. –  Sep 18 '13 at 03:51
  • @ Lego Stormtroopr i was refering to josh xD. I can understand why a goto might turn into a nightmare now. – Calder Hutchins Sep 18 '13 at 03:53
  • More pythonic would be `if number % 2: print 'odd' else: print 'even'` – Burhan Khalid Sep 18 '13 at 05:48
  • @BurhanKhalid Its would be, but I was writing it to be very explicit code. –  Sep 18 '13 at 05:52
  • 27
    “`goto`s are universally reviled in computer science and programming”—not quite. `goto` is perfect for error handling in C (eschewing RAII and exceptions), and for implementing structured programming constructs. Absolute statements are always—well, often—misguided. – Jon Purdy Sep 18 '13 at 07:16
  • @JonPurdy I originally had "considered universally reviled" which was a little less absolute. I didn't intent to argue the edit. You are right, they have their place as Tovalds and Knuth argued. However given the question, and the audience, I felt an absolute was ok. –  Sep 18 '13 at 07:45
  • 10
    I won't go against the universally accepted opinion that "goto is bad" (although I personally don't believe it), but I have to bring up a simple, also universal, fact: All executable codes, from all languages, result to machine (assembly) code, which is actually *based* on jumps! I am an assembly programmer and I never had a problem tracing back a jump and find the condition that had led to it, even if the *source* code wasn't mine. – Apostolos Jan 14 '18 at 17:57
  • So conditionally jumping to a particular part of the code isnt structured? GOTO functions exist at the assembly level and have legitimate purpose. There is no reason to remove functionality from a higher level language than what exists at the lower level. – CogitoErgoCogitoSum Feb 10 '18 at 20:07
  • an example of a bad program using goto does not answer the question – Jasen Feb 28 '18 at 22:04
  • 11
    Try writing command parsers and methods that take config inputs that can lead to many different combination of possible code paths and you will realize why GOTO / JUMP are the best fit for such situations. GOTO allows you to write the cleanest code in such situations. Lets not be so dogmatic. – rjha94 Mar 10 '18 at 11:42
  • 8
    Like several other commenters, I disagree with the opinion that “`goto`s are universally reviled”. `goto`s are _dangerous_ because they _can_ lead to very unstructured code, and a beginner programmer would tend to use `goto` this bad way. *But* in _some_ situations `goto`s are really useful and actually lead to a _better_ code! So a more accurate answer would be: “Python does not allow for `goto`, to avoid beginner programmers to be tempted to misuse it”. – Rémi Peyre Apr 23 '18 at 21:41
  • I'm working on a fortran to Python code conversion and that's pretty much I've implemented. Unstructured to Structured says it all!! – NightOwl19 Aug 13 '18 at 08:11
  • In a sense 'gotos' can be considered best practice: just write a statemachine, and convert your labels to states. So now no more gotos and if I remember correctly statemachines are considered good. (and the code even looks similiar) – lalala Jun 20 '20 at 15:19
  • Re: `goto` *universally reviled*—[GOTOphobia considered harmful (in C)](https://blog.joren.ga/gotophobia-harmful). That is about *C*, but Python is also largely procedural/imperative, and has the same basic facilities of control-flow. – Anton Shepelev Mar 02 '23 at 08:31
45

I entirely agree that goto is poor poor coding, but no one has actually answered the question. There is in fact a goto module for Python (though it was released as an April fool joke and is not recommended to be used, it does work).

scohe001
  • 15,110
  • 2
  • 31
  • 51
9

There's no goto instruction in the Python programming language. You'll have to write your code in a structured way... But really, why do you want to use a goto? that's been considered harmful for decades, and any program you can think of can be written without using goto.

Of course, there are some cases where an unconditional jump might be useful, but it's never mandatory, there will always exist a semantically equivalent, structured solution that doesn't need goto.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    Thank-you, I wanted to use it to: python askes the user a question and if the raw input is not yes or no it will ask another question about what the user meant. Then it would go back to the line before the question was asked. – Calder Hutchins Sep 18 '13 at 03:27
  • @CalderHutchins Can you explain what you mean by if it's not yes or not it asks another question? – C0deH4cker Sep 18 '13 at 03:29
  • 2
    @CalderHutchins: That's trivial to do in a structured flow. There's no need to create any jumps to arbitrary lines. – Makoto Sep 18 '13 at 03:30
  • 2
    @CalderHutchins you don't need a `goto` for that, put the question inside a loop, if the answer is not valid then loop again until the input is right – Óscar López Sep 18 '13 at 03:30
  • I mean if you do not asnswer the question with yes or no, python will ask you if the answer you gave is similar to yes, or to no, basically i want it to learn by itself, of which i will have to find out how to make python edit it's own code, like BATCH can. – Calder Hutchins Sep 18 '13 at 03:32
  • 5
    well *never need goto* and *there is always always structured equivalent* is true enough for python, but that's something you couldn't truly write when including assembly languages in the scope. Also python still has break and return which are gotos in disguise, and Exceptions are also arguably gotos in disguise. – kriss Sep 18 '13 at 08:36
  • @CalderHutchins You would be much better off using regex to check the input against a known list of possible variations which as others have suggested is easy to do with a simple while loop. If you want Python to write its own code, which it can, you may but it would have to write it to another file that's not in use and then run that file whichever way you choose. – democidist Apr 02 '18 at 02:06
7

Disclaimer: I have been exposed to a significant amount of F77

The modern equivalent of goto (arguable, only my opinion, etc) is explicit exception handling:

Edited to highlight the code reuse better.

Pretend pseudocode in a fake python-like language with 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'.

Compared to 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'

Explicit named exceptions are a significantly better way to deal with non-linear conditional branching.

Caleb Hattingh
  • 9,005
  • 2
  • 31
  • 44
  • 1
    That's not a bad way of thinking about the *best possible* use of non-local gotos – msw Sep 18 '13 at 03:51
  • 2
    Truth: >95% of GOTOs I have seen in the wild have been used for preemptive error handling. The other 5% have been clever tricks that resulted in horrific bugs, and the code, as-is, couldn't even **be** translated to a different goto-less language without requiring changes to the algorithm. – Caleb Hattingh Sep 18 '13 at 03:55
  • @crjh: I'm very interested in seeing codes with `goto`s that cannot be directly translated to `goto`-less language. Can you give me example? – justhalf Sep 18 '13 at 03:57
  • Think of multiple nested loops that `goto` between each other...a lot... – Caleb Hattingh Sep 18 '13 at 03:59
  • 2
    @justhalf I can't find the exact paper, but there is a proof that **all** programs that use `goto` can be rewritten to use while loops instead. Not cleanly mind you, but you can remove all `goto`s. –  Sep 18 '13 at 04:19
  • 2
    @LegoStormtroopr: you should be addressing that to cjrh, haha But yeah, I guess the "not cleanly" part is what cjrh referred to as "requiring changes to the algorithm" – justhalf Sep 18 '13 at 04:24
  • @Lego Stormtroopr: this is easy enough to prove. You can replace any goto using some memorized states. Usually even in difficult cases some booleans are enough, but you can look at the answer of Tim Peters as a proof that gotos are never necessary (because you can simulate them without having gotos). – kriss Sep 18 '13 at 08:41
4
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"

Would give you what you want with no goto statement.

Paul Becotte
  • 9,767
  • 3
  • 34
  • 42