Python中的`goto`

Alb*_*ert 29 python bytecode goto compilation

我必须goto在Python中使用.我发现了托管,goto但我的Python实现(Mac上的CPython 2.7.1)没有这个模块,所以它似乎不是可移植的.它应该至少适用于支持CPython字节码的所有Python实现(特别是我关心CPython和PyPy).然后有这个相关的问题,和cdjc的goto.以下是答案给出的.

我可以手动构建字节码(即编写我自己的Python编译器)因为有这样的指令(JUMP_ABSOLUTE和朋友).但我想知道是否有更简单的方法.是否可以通过inspect左右来调用单个字节码指令?我还想过通过Python编译然后自动修补生成的Python字节码.


当然,如果我不解释为什么我真的需要这个,人们会问为什么,不会给我任何有用的答案.所以简而言之我的用例:我正在将一个C AST翻译成Python AST并编译它.我可以用某种方式将每个逻辑流(所有循环和其他东西)映射到等效的Python代码.除了之外的一切goto.相关项目:PyCParser(参见参考资料interpreter.py),PyCPython,PyLua.

Pao*_*tti 44

我知道每个人都在想什么:

xkcd GOTO

但是,可能存在一些您实际需要的教学案例goto.

这个python配方提供了goto作为函数装饰器的命令.

goto装饰器( Carl Cerecke的Python配方)

如果您厌倦了现有goto模块http://entrian.com/goto/的低速,这就是您的秘诀.在goto这个配方是约60倍的速度更快,也更清洁(滥权sys.settrace 似乎很难符合Python).因为这是一个装饰器,它会提醒读者哪些功能使用goto.它没有实现comefrom命令,尽管扩展它并不困难(为读者练习).此外,不支持计算的gotos; 他们不是pythonic.

  • 使用dis.dis(fn)显示功能的字节码拆卸.
  • 函数的字节码可通过以下方式访问fn.func_code.co_code.这是只读的:
  • 已创建的装饰函数与旧函数完全相同,但更新了字节码以遵守goto命令.
  • 这只是2.x; 新模块不在python 3.x中(读者的另一个练习!)

用法

@goto
def test1(n):
    s = 0

    label .myLoop

    if n <= 0:
        return s
    s += n
    n -= 1

    goto .myLoop

>>> test1(10)
55
Run Code Online (Sandbox Code Playgroud)

更新

这是与Python 3兼容的两个额外实现:

  • 有趣的是,配方作者正在考虑"pythonicity"("滥用sys.settrace似乎很难pythonic")实现goto :)无论如何,很棒的答案! (10认同)

kin*_*all 8

您可能拥有我goto在Python中看到的唯一有效用例.:-)

goto在Python中模拟前进的最直接的方法是使用异常,因为这些异常可以跳出任何深度的嵌套控件结构.

class Goto(Exception):
    pass

try:
    if foo = "bar":
        raise Goto
    print "foo is not bar"
except Goto:
    print "foo is bar"
Run Code Online (Sandbox Code Playgroud)

如果您需要支持多个目标,这会变得毛茸茸,但我认为可以使用嵌套try/except结构和多个异常类来完成,每个目标一个.由于C限制goto了单个函数的范围,至少您不必担心如何函数使这个工作.:-)当然,它不适用于反向goto.

另外需要注意的是,Python中的异常虽然与某些语言相比速度较快,但仍然比正常的流控制结构(例如while和)慢for.

这可能是很多工作(虽然可能不比你已经有的多),但是如果你可以生成Python字节码而不是Python源代码,那么实现起来就没有问题goto,因为Python字节码(就像大多数伪代机器一样)语言)有一个完美的运算JUMP_ABSOLUTE代码.


cdj*_*djc 5

我已经为Python 3更新了我的python goto decorator.你可以在https://github.com/cdjc/goto上找到它.使用goto而不是函数可以使状态机大约快5倍.

python 2的版本仍然可以在http://code.activestate.com/recipes/576944-the-goto-decorator/上找到,但它有许多在python 3版本中修复的错误.

  • "使用goto代替函数可以使状态机快5倍." - 最初学会用现在古老的BASIC方言编程(其中GOTO和GOSUB是*唯一*流控制)我经常发现自己解释对于那些被教导过"goto本质上是邪恶的"的年轻程序员来说,goto实际上更像是炸药.在专家手中,它可以以清晰,简洁,快速可执行的方式从代码路径中消除主要障碍.在一个白痴的手中,它导致你的代码的粘性gobbets被遍布整个景观...... (4认同)