51

我正在自学python 2.7。我有一些使用 BATCH 的经验,它有一个 GOTO 语句。我如何在 python 中做到这一点?例如,假设我想从第 5 行跳到第 18 行。

我意识到以前有关于这个主题的问题,但我没有发现它们提供足够的信息,或者对于我目前的理解来说,它们在 python 中的水平太高了。

4

6 回答 6

73

原谅我 - 我无法抗拒;-)

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)
于 2013-09-18T03:45:38.730 回答
67

Gotos 在计算机科学和编程中受到普遍谴责,因为它们会导致非常非结构化的代码。

Python(就像今天几乎所有的编程语言一样)支持结构化编程,它使用 if/then/else、循环和子例程来控制流程。

以结构化方式思考的关键是了解如何以及为什么要在代码上进行分支。

例如,假设 Python 有一个goto相应的label语句shudder。看下面的代码。如果一个数字大于或等于 0,我们打印它

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"

如果我们想知道一段代码何时执行,我们需要在程序中仔细回溯,并检查标签是如何到达的——这实际上是无法做到的。

例如,我们可以将上面的内容重写为:

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"

在这里,有两种可能的方式可以到达“终点”,我们无法知道选择了哪一种。随着程序变大,这种问题会变得更糟,并导致意大利面条代码

相比之下,下面是你如何用 Python 编写这个程序:

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

我可以查看特定的代码行,并通过追溯if/then/else它所在的块树来了解在什么条件下满足它。例如,我知道print "odd"((number >= 0) == True) and ((number % 2 == 0) == False).

于 2013-09-18T03:35:47.657 回答
41

我完全同意这goto是糟糕的编码,但没有人真正回答过这个问题。实际上有一个用于 Python 的 goto 模块(尽管它是作为愚人节玩笑发布的,不建议使用,但它确实有效)。

于 2013-09-18T03:53:23.793 回答
9

Python 编程语言中没有goto指令。您必须以结构化的方式编写代码...但实际上,您为什么要使用goto? 几十年来这一直被认为是有害的,任何你能想到的程序都可以在不使用goto.

当然,在某些情况下,无条件跳转可能有用,但绝不是强制性的,总会存在不需要的语义等价的结构化解决方案goto

于 2013-09-18T03:23:29.007 回答
7

免责声明:我接触过大量的 F77

goto(有争议,只有我的意见等)的现代等价物是显式异常处理:

编辑以更好地突出代码重用。

用伪类 python 语言假装伪代码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'.

与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'

显式命名异常是处理非线性条件分支的明显更好的方法。

于 2013-09-18T03:39:45.067 回答
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"

无需 goto 语句即可满足您的需求。

于 2013-09-18T04:30:03.447 回答