unw*_*ind 107
不,Python不支持标签和goto,如果这是您所追求的.它是一种(高度)结构化的编程语言.
Jas*_*ker 67
Python为您提供了使用第一类函数执行goto所能完成的一些功能.例如:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
Run Code Online (Sandbox Code Playgroud)
可以像这样在python中完成:
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
Run Code Online (Sandbox Code Playgroud)
当然,这不是替代goto的最佳方式.但是如果不确切地知道你要对goto做什么,很难给出具体的建议.
@ ascobol:
最好的办法是将其包含在函数中或使用异常.对于功能:
def loopfunc():
while 1:
while 1:
if condition:
return
Run Code Online (Sandbox Code Playgroud)
对于例外:
try:
while 1:
while 1:
raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
pass
Run Code Online (Sandbox Code Playgroud)
如果你来自另一种编程语言,使用异常来做这样的事情可能会有点尴尬.但我认为,如果您不喜欢使用异常,Python就不适合您.:-)
Seb*_*ack 47
我最近写了一个函数装饰器,goto在Python 中启用,就像这样:
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
Run Code Online (Sandbox Code Playgroud)
我不确定为什么人们会这样做.那就是说,我对此并不太认真.但是我想指出,这种元编程在Python中是可行的,至少在CPython和PyPy中,并且不仅仅是像其他人那样滥用调试器API .你必须弄乱字节码.
kla*_*aas 21
我在官方的python设计和历史常见问题中找到了这个.
为什么没有转到?
您可以使用异常来提供甚至可以跨函数调用工作的"结构化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
...
Run Code Online (Sandbox Code Playgroud)
这不允许你跳到循环的中间,但这通常被认为是滥用goto.谨慎使用.
在官方常见问题解答中甚至提到这一点非常好,并且提供了一个很好的解决方案示例.我真的很喜欢python,因为它的社区goto就像这样对待;)
jfs*_*jfs 15
使用评论中的建议回答@ascobol问题@bobince:
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
Run Code Online (Sandbox Code Playgroud)
else块的缩进是正确的.代码else在循环Python语法之后使用模糊.看看为什么python在for循环和while循环之后使用'else'?
har*_*rmv 12
已经制作了一个工作版本: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\n"
Run Code Online (Sandbox Code Playgroud)
不用说.是的它有趣,但不要使用它.
pip3 install goto-statement
Run Code Online (Sandbox Code Playgroud)
在 Python 2.6 到 3.6 和 PyPy 上测试。
链接:goto 语句
文件
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
Run Code Online (Sandbox Code Playgroud)
您可以使用用户定义的异常来模拟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()
Run Code Online (Sandbox Code Playgroud)
通过一些工作向python添加'goto'之类的语句在技术上是可行的.我们将使用"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()
Run Code Online (Sandbox Code Playgroud)
希望这能回答这个问题.
| 归档时间: |
|
| 查看次数: |
354860 次 |
| 最近记录: |