The equivalent of a GOTO in python
我正在自学python 2.7。 我在使用具有GOTO语句的BATCH方面有一些经验。 我该如何在python中做到这一点? 例如,假设我要从第5行跳到第18行。
我意识到以前有关于此主题的问题,但是我发现它们没有足够的信息,或者对于我目前的理解而言,对于python来说太高了。
-
@kojiro请阅读整个主题。
-
"一个人提到了一个功能,但我不知道它们如何工作。" 了解功能如何工作,然后您将看到不需要goto。
-
好吧,我去做那阿卡瓦尔
-
随机:如果您确实想使用goto,则实际上有人在2004年愚人节玩笑中写了一个工作版本。我绝不建议您实际使用它,但出于娱乐考虑,我认为应该将其链接。
-
我认为无论如何,您都必须使用while循环来处理它。
-
在某些情况下,如果id没有其他结构构造可以做您想要的事情,则可以使用异常来实现类似goto的行为。
-
答案可在stackoverflow.com/questions/438844/中获得。 仅使用goto语句就可以很好地处理函数中的故障。
原谅我-我无法抗拒;-)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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) |
-
大声笑!卡尔德,这是个玩笑。可以用任何语言编写可怕的代码;-)
-
请从下一个实现吗?
-
大声笑蒂姆,我知道这是个玩笑:p
-
它表明您具有良好的编程能力:)确实是在开玩笑
-
保留行号到函数的字典是否更pythonic?像这样。还是最好使end提出一些建议?
-
大声笑-爱lambdas!当然,关键是要使其尽可能地不符合Python风格,并且扭曲的lambda肯定会帮助它;-)
goto在计算机科学和编程中普遍受到谴责,因为它们会导致非常非结构化的代码。
Python(像当今几乎所有编程语言一样)都支持结构化编程,该结构使用if / then / else,循环和子例程控制流。
以结构化方式进行思考的关键是理解如何以及为什么要分支代码。
例如,让我们假装Python有一个goto和相应的label语句抖动。看下面的代码。如果数字大于或等于0,则在其中打印
1 2 3 4 5 6 7 8 9 10 11
| 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" |
如果我们想知道何时执行一段代码,则需要仔细地在程序中进行追溯,并检查标签是如何到达的-这实际上是做不到的。
例如,我们可以将以上内容重写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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编写该程序的方式:
1 2 3 4 5 6 7 8 9
| number = input()
if number >= 0:
if number % 2 == 0:
print"even"
else:
print"odd"
else:
print"negative"
print"all done" |
我可以查看特定的代码行,并通过追溯其所在的if/then/else块树来了解在什么条件下可以满足它。例如,我知道当。
-
@kojiro谢谢!固定。
-
+1,您的解释很棒,所有代码看起来都不错,但是随着脚本越来越大,您可能无法单行处理负数。 if / else开始在屏幕上缩进堆积。如果在本示例中您接受输入,则调用check(),如果发现数字为负,则在check()中调用negative(),可能会更好。此外,这将表明采用label并直接使用函数是多么容易(我们的OP似乎并没有完全掌握它)
-
@CalderHutchins从表面上看,goto看上去无害,对新程序员来说直截了当-"去这个地方做事"。很多时候,为什么会迷失在时间的迷思中,但是结构化编程的原理仍然存在。
-
我只是在学习Python的第三天才休息一下;)
-
@Josh如果您的代码在屏幕上缩进,则表示箭头反模式。它不是反对结构化编程的论据,而只是反对思想较差的程序的论点。
-
我了解@LegoStormtroopr,这就是为什么我试图在这样一个简单的示例中告诉我教给OP使用函数以避免这种情况,然后再将其中一个程序员派上用场(正如我之前说的,他似乎没有非常了解功能)
-
@CalderHutchins不要以为我的评论"在表面价值上……"是对您的侮辱或针对。关于其他程序员为什么要问goto的更多解释。它们看起来确实很直观,并且在小型程序中也是如此。 goto的问题要等到成千上万行,这里的快捷方式,那里的快捷方式,然后是无法维持的噩梦之后才会出现。
-
@ Lego Stormtroopr我指的是乔什xD。我能理解为什么goto可能现在变成一场噩梦。
-
更多pythonic将是if number % 2: print odd else: print even
-
@BurhanKhalid确实如此,但是我在编写它是非常明确的代码。
-
" goto在计算机科学和编程中普遍受到谴责" –并非如此。 goto非常适合C语言中的错误处理(避开RAII和异常),以及实现结构化的编程构造。绝对陈述总是(经常是)被误导。
-
@JonPurdy我最初曾"认为普遍受到谴责",这绝对没有那么一点。我无意争辩该编辑。没错,正如托瓦尔兹(Tovalds)和克努斯(Knuth)所说,他们有自己的位置。但是考虑到这个问题和听众,我觉得绝对可以。
-
我不会反对公认的" goto不好"的观点(尽管我个人不相信),但是我必须提出一个简单的,也是通用的事实:所有语言的所有可执行代码,都将结果存入机器(汇编) )代码,它实际上是基于跳转的!我是一名汇编程序员,即使源代码不是我的,我也没有问题可以追溯到跳转并找到导致这种情况的条件。
-
那么有条件地跳转到没有结构化的代码的特定部分吗? GOTO功能存在于汇编级别,并且具有合法目的。没有必要从较高级别的语言中删除功能而不是较低级别的语言。
-
使用goto的不良程序的示例无法回答问题
-
尝试编写使用配置输入的命令解析器和方法,这些输入可能导致可能的代码路径发生许多不同的组合,您将了解为什么GOTO / JUMP最适合此类情况。在这种情况下,GOTO允许您编写最干净的代码。让我们不要那么教条。
-
像其他一些评论者一样,我不同意" goto被普遍谴责"的观点。 goto很危险,因为它们可能导致非常结构化的代码,并且初学者会倾向于以这种不好的方式使用goto。但是在某些情况下,goto确实有用,并且实际上可以导致更好的代码!因此,更准确的答案是:" Python不允许goto,以避免初学者程序员被滥用。"
-
我正在进行从Fortran到Python代码的转换,而Ive几乎已经实现了。非结构化到结构化就说明了一切!
我完全同意goto的编码不好,但是实际上没有人回答过这个问题。实际上,有一个用于Python的goto模块(尽管它是愚人节玩笑发布的,不建议使用,但它确实可以工作)。
-
从Python 2.6.9开始,它不再起作用...
-
连续传递样式需要goto(以函数调用的形式)。
Python编程语言中没有goto指令。您必须以结构化的方式编写代码...但是,实际上,为什么要使用goto?几十年来一直被认为是有害的,并且您可以想到的任何程序都可以在不使用goto的情况下编写。
当然,在某些情况下无条件跳转可能很有用,但它不是强制性的,总会存在不需要goto的语义等效的结构化解决方案。
-
谢谢,我想将其用于:python向用户询问一个问题,如果原始输入不是yes或no,它将询问有关用户含义的另一个问题。然后它将返回到询问该问题之前的那一行。
-
@CalderHutchins如果不是或不是,您会问另一个意思吗?
-
@CalderHutchins:在结构化流程中这样做很简单。无需创建到任意行的任何跳转。
-
@CalderHutchins不需要goto,将问题放入循环中,如果答案无效,则再次循环直到输入正确为止
-
我的意思是,如果您不回答"是"或"否",python会询问您给出的答案是否与"是"或"否"相似,基本上我想让它自己学习,我将必须找出方法像BATCH一样使python编辑自己的代码。
-
永远都不需要goto,而且对于python来说,总是有结构化的等效项就足够了,但这就是在范围内包括汇编语言时您无法真正编写的东西。同样,python仍然具有折返的折返,这是伪装的getos,并且异常也可以说是伪装的gotos。
-
@CalderHutchins使用正则表达式检查输入的已知变量列表可能会好得多,正如其他人建议的那样,使用简单的while循环很容易做到这一点。如果您希望Python编写自己的代码,可以这样做,但可以,但必须将其写入另一个未使用的文件,然后以您选择的任何方式运行该文件。
免责声明:我接触了大量的F77
goto的现代等效项(可以争论,只有我自己的观点,等等)是显式异常处理:
编辑以突出代码重用性更好。
用goto将伪代码伪装成类似python的伪语言:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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相比:
1 2 3 4 5 6 7 8 9 10 11 12
| def myfunc1(x):
return 1/x
def myfunc2(y):
return 1/y
try:
myfunc1(0)
myfunc2(0)
except ZeroDivisionError:
print 'Cannot divide by zero' |
显式命名异常是处理非线性条件分支的一种更好的方法。
-
那是考虑最佳使用非本地方法的好方法
-
真相:我在野外看到的超过95%的GOTO已用于抢先式错误处理。其余5%是巧妙的技巧,这些技巧导致了可怕的错误,并且即使不修改算法,也无法将代码按原样翻译成其他的goto-less语言。
-
@crjh:我非常想看到不能直接翻译成goto -less语言的goto代码。能举个例子吗?
-
想想彼此之间很多goto的多个嵌套循环...
-
@justhalf我找不到确切的论文,但是有证据表明,所有使用goto的程序都可以重写为使用while循环。不必介意,但是您可以删除所有goto。
-
@LegoStormtroopr:您应该在cjrh上解决这个问题,哈哈,是的,我想cjrh所说的"不干净"部分是"要求对算法进行更改"
-
@Lego Stormtroopr:这很容易证明。您可以使用某些记忆状态替换任何goto。通常,即使在困难的情况下,也可以使用一些布尔值就足够了,但是您可以将蒂姆·彼得斯的答案看作是绝对不需要goto的证明(因为您可以在没有gotos的情况下模拟它们)。
1 2 3 4 5
| 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语句即可为您提供所需的内容。
-
这不是一个好主意。尽管从技术上讲它是正确的,但它使逻辑很难解开。
-
它比goto更好。