相当于python中的GOTO

Cal*_*ins 42 python goto

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

我意识到之前有关于这个主题的问题,但我没有发现它们足够的信息,或者在我目前的理解中python级别太高.

小智 57

Goto在计算机科学和编程方面普遍受到谴责,因为它们会导致非结构化的代码.

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

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

例如,让我们假装Python有一个goto相应的label声明颤抖.请查看以下代码.如果数字大于或等于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"
Run Code Online (Sandbox Code Playgroud)

如果我们想知道何时执行一段代码,我们需要在程序中仔细追溯,并检查标签是如何到达的 - 这是无法真正完成的.

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

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"
Run Code Online (Sandbox Code Playgroud)

在这里,有两种可能的方式来达到"结束",我们无法知道选择了哪一种.随着程序变得越来越大,这种问题会变得更糟,并导致意大利面条代码

相比较而言,下面是你如何在Python编写这个程序:

number = input()
if number >= 0:
   if number % 2 == 0:
       print "even"
   else:
       print "odd"
else:
   print "negative"
print "all done"
Run Code Online (Sandbox Code Playgroud)

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

  • "`goto`s在计算机科学和编程方面普遍受到谴责" - 并非如此.`goto`非常适合C中的错误处理(避开RAII和异常),以及实现结构化编程结构.绝对陈述总是很好,经常被误导. (6认同)
  • 尝试编写命令解析器和方法,这些解析器和方法采用可导致许多不同组合的可能代码路径的配置输入,您将了解为什么GOTO/JUMP最适合此类情况.GOTO允许您在这种情况下编写最干净的代码.让我们不那么教条. (4认同)
  • 像其他几位评论者一样,我不同意“`goto`s 普遍受到谴责”的观点。`goto` 是_危险的_,因为它们_可能_导致非常非结构化的代码,并且初学者程序员倾向于以这种糟糕的方式使用 `goto`。*但是*在_某些_情况下,`goto`s 非常有用并且实际上会导致_更好_的代码!因此,更准确的答案是:“Python 不允许使用 `goto`,以避免初学者误用它”。 (4认同)
  • +1,你的解释很好,并且所有代码看起来都很好,但随着脚本变得越来越大,你可能无法在一行中处理负数.if/else开始堆积屏幕上的缩进.如果在这个例子中你接受输入,调用`check()`,并且在`check()`中,如果我们发现数字为负数,则调用`negative()`可能更好.此外,这将显示采用`label`s并直接执行功能(我们的OP似乎并不完全掌握)是多么容易 (2认同)
  • 我不会违背公认的“ goto不好”的观点(尽管我个人不相信),但是我必须提出一个简单的,也是普遍的事实:所有语言的所有可执行代码都会产生结果加工(汇编)代码,它实际上是基于跳跃的*!我是一名汇编程序员,即使* source *代码不是我的,我也没有问题可以追溯到跳转并找到导致这种情况的条件。 (2认同)

Tim*_*ers 57

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

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)
Run Code Online (Sandbox Code Playgroud)

  • 大声笑!考尔德,这是个玩笑.有可能用**任何**语言编写可怕的代码;-) (35认同)
  • 请执行[来自](https://en.wikipedia.org/wiki/COME_FROM)下一步? (7认同)
  • 将行号的字典保存到函数中不是更加pythonic吗?喜欢[这个](http://pastebin.com/eqDksSnM)也许吧.或者让"结束"提高某些东西会更好吗? (4认同)
  • 嗯有趣,+1 (3认同)

sco*_*001 35

我完全同意这goto是糟糕的编码,但没有人真正回答过这个问题.还有就是其实是一个为Python转到模块(尽管它被发布了作为一个愚人节的玩笑,不建议使用,但工作).

  • 从 Python 2.6.9 开始,它不再工作了...... (2认同)

Ósc*_*pez 9

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

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

  • @CalderHutchins:在结构化流程中这样做很简单。无需创建到任意行的任何跳转。 (2认同)
  • @CalderHutchins你不需要`goto`,把问题放在一个循环中,如果答案无效,那么再循环直到输入正确 (2认同)
  • 很好,*永远不需要goto *,并且*总是总是有结构上等价的*对于python来说确实足够,但这是在范围中包括汇编语言时您无法真正编写的东西。同样,python仍然具有折返的折返,这是伪装的getos,并且异常也可以说是伪装的gotos。 (2认同)

Cal*_*ngh 6

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

现代等价的goto(可论证的,只有我的观点等)是明确的异常处理:

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

伪装成伪蟒蛇语言中的伪代码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'.
Run Code Online (Sandbox Code Playgroud)

与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'
Run Code Online (Sandbox Code Playgroud)

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

  • 真相:我在野外看到的 95% 以上的 GOTO 都被用于抢占式错误处理。其他 5% 是聪明的技巧,导致了可怕的错误,并且代码甚至无法在不需要更改算法的情况下**被**翻译为不同的 goto-less 语言。 (2认同)
  • @justhalf 我找不到确切的论文,但有证据表明 **所有** 使用 `goto` 的程序可以改写为使用 while 循环。不完全介意你,但你可以删除所有`goto`s。 (2认同)
  • @LegoStormtroopr:你应该向 cjrh 解决这个问题,哈哈但是是的,我想“不干净”的部分就是 cjrh 所说的“需要更改算法” (2认同)