Python 中有标签/goto 吗?
- 2024-12-30 08:42:00
- admin 原创
- 75
问题描述:
Python 中是否有goto
可以跳转到特定代码行的函数?
解决方案 1:
不,Python 不支持标签和 goto。它是一种(高度)结构化的编程语言。
解决方案 2:
Python 让你能够使用一流函数执行一些使用 goto 可以完成的操作。例如:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
可以用 Python 像这样完成:
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
当然,这不是替代 goto 的最佳方法。但如果不知道你到底想用 goto 做什么,就很难给出具体的建议。
@ascobol :
最好的办法是将其包含在函数中或使用异常。对于该函数:
def loopfunc():
while 1:
while 1:
if condition:
return
对于例外情况:
try:
while 1:
while 1:
raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
pass
如果您来自其他编程语言,使用异常来做这样的事情可能会感觉有点尴尬。但我认为,如果您不喜欢使用异常,那么 Python 不适合您。:-)
解决方案 3:
我最近写了一个在 Python 中启用的函数装饰器goto
,就像这样:
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
不过,我不确定为什么有人会想做这样的事情。话虽如此,我对此并不太认真。但我想指出的是,这种元编程在 Python 中实际上是可能的,至少在 CPython 和 PyPy 中是可能的,而不仅仅是像其他人那样滥用调试器 API 。不过,你必须弄乱字节码。
解决方案 4:
我在官方的 Python 设计和历史常见问题解答中找到了这一点。
为什么没有 goto?
您可以使用异常来提供“结构化 goto”,甚至可以跨函数调用使用。许多人认为异常可以方便地模拟 C、Fortran 和其他语言的“go”或“goto”结构的所有合理用法。例如:
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
这不允许您跳转到循环中间,但这通常被认为是对 goto 的滥用。请谨慎使用。
官方常见问题解答中甚至提到了这一点,并且提供了一个很好的解决方案示例,这非常好。我真的很喜欢 Python,因为它的社区甚至如此对待goto
它 ;)
解决方案 5:
已制作了一个工作版本: http: //entrian.com/goto/。
注:这只是一个愚人节玩笑。(但有效)
# 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
"
不用说。是的,这很有趣,但不要使用它。
解决方案 6:
使用评论中的建议来回答@ascobol
的问题:@bobince
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
块的缩进else
是正确的。代码else
在循环后使用了模糊的 Python 语法。请参阅为什么 Python 在 for 和 while 循环后使用“else”?
解决方案 7:
Python 2 和 3
pip3 install goto-statement
在 Python 2.6 至 3.6 和 PyPy 上进行了测试。
链接:goto 语句
foo.py
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
解决方案 8:
从技术上讲,只要做一些工作,就可以将类似“goto”的语句添加到 Python 中。我们将使用“dis”和“new”模块,这两个模块对于扫描和修改 Python 字节码都非常有用。
实现背后的主要思想是首先使用“goto”和“label”语句标记代码块。将使用特殊的“@goto”装饰器来标记“goto”函数。然后我们扫描该代码以查找这两个语句,并对底层字节码应用必要的修改。这一切都发生在源代码编译时。
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()
希望这能回答这个问题。
解决方案 9:
早在 2007 年, PEP 3136就提出了break
和的标签,但被否决了。该提案的动机部分说明了在 Python 中模仿标签的几种常见(尽管不够优雅)方法。continue
`break`
解决方案 10:
您可以使用用户定义的异常来模拟goto
例子:
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()
解决方案 11:
在实现“goto”时,首先要问什么是 goto。虽然这看起来很明显,但大多数人并没有考虑 goto 与函数堆栈有何关系。
如果您在函数内部执行“goto”,则实际上会放弃函数调用堆栈。这被认为是不好的做法,因为函数堆栈的设计期望您在委托中间任务后继续执行上次中断的操作。这就是为什么 goto 用于异常的原因,而异常可用于模拟 goto,我将对此进行解释。
有限状态机可能是 goto 的最佳用例,大多数情况下 goto 都是用循环和 switch 语句以笨拙的方式实现的,但我相信“顶级” goto 是实现有限状态机最干净、最语义化的方式。在这种情况下,您要确保,如果您有更多变量,它们是全局变量,并且不需要封装。确保您首先对变量状态空间进行建模(这可能与执行状态不同,即有限状态机)。
我认为使用 goto 有合理的设计理由,异常处理是将 goto 与函数混合使用的特殊情况。但是,在大多数情况下,您希望将自己限制在“顶级”goto 中,因此您永远不会在函数内调用 goto,而只能在全局范围内调用 goto。
在现代语言中模拟顶层 goto 的最简单方法是认识到顶层 goto 只需要全局变量和一个空的调用堆栈。因此,为了保持调用堆栈为空,每当调用新函数时都要返回。以下是打印前 n 个斐波那契数的示例:
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()
虽然此示例可能比循环实现更冗长,但它也更强大、更灵活,并且不需要特殊情况。它让您拥有一个完整的有限状态机。您还可以使用 goto 运行器对其进行修改。
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)
为了强制“返回”部分,您可以编写一个 goto 函数,当完成时只需抛出异常。
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)
所以你看,很多都是想多了,一个调用函数然后抛出错误的辅助函数就是你所需要的。你可以进一步将其包装在“start”函数中,这样错误就会被捕获,但我认为这不是绝对必要的。虽然其中一些实现可能会耗尽你的调用堆栈,但第一个运行器示例会将其保持为空,如果编译器可以进行尾部调用优化,那也会有所帮助。
解决方案 12:
我正在寻找类似的东西
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;
所以我的方法是使用布尔值来帮助跳出嵌套的 for 循环:
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
解决方案 13:
虽然没有与goto/label
Python 中等效的代码,但您仍然可以获得goto/label
使用循环的此类功能。
让我们看下面显示的一个代码示例,其中goto/label
可以在除 Python 之外的任意语言中使用。
String str1 = 'BACK'
label1:
print('Hello, this program contains goto code
')
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
Bla bla bla...
Bla bla bla...
Bla bla bla...')
现在可以通过使用循环在 Python 中实现上述代码示例的相同功能while
,如下所示。
str1 = 'BACK'
while str1 == 'BACK':
print('Hello, this is a python program containing python equivalent code for goto code
')
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
Bla bla bla...
Bla bla bla...
Bla bla bla...')
解决方案 14:
您可以使用 python 中的嵌套方法来实现它
def func1():
print("inside func1")
def inline():
print("im inside")
inline()
func1()
解决方案 15:
现在有了。转到
我认为这可能对于您正在寻找的内容有用。
解决方案 16:
我想要相同的答案,但我不想使用goto
。所以我使用了以下示例(来自 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)
解决方案 17:
我有自己的执行 goto 的方法。我使用单独的 python 脚本。
如果我想循环:
文件1.py
print("test test")
execfile("file2.py")
a = a + 1
文件2.py
print(a)
if a == 10:
execfile("file3.py")
else:
execfile("file1.py")
文件3.py
print(a + " equals 10")
(注意:此技术仅适用于 Python 2.x 版本)
解决方案 18:
对于前向 Goto,您只需添加:
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
但这只对简单的场景有帮助(即嵌套这些会让你陷入混乱)
解决方案 19:
代替 python goto 等效项,我以以下方式使用 break 语句来快速测试我的代码。这假设您有结构化的代码库。测试变量在函数开始时初始化,我只需将“If test: break”块移动到我要测试的嵌套 if-then 块或循环的末尾,修改代码末尾的返回变量以反映我正在测试的块或循环变量。
def x:
test = True
If y:
# some code
If test:
break
return something
解决方案 20:
没有,有另一种方法来实现 goto 语句
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 age")
for i in range(n):
print(name[i]," ",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 age")
for i in range(n):
print(name[i]," ",age[i])
n=-1
p1=id()
p1.data1()
解决方案 21:
我认为您可以在代码中创建函数,如果某些条件为真,您可以直接调用该函数,而不是使用 goto。
解决方案 22:
我认为 while 循环是“goto_Statement”的替代品。因为 3.6 之后 goto 循环不再起作用。我还写了 while 循环的示例。
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")
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件