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
我知道每个人都在想什么:
但是,可能存在一些您实际需要的教学案例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兼容的两个额外实现:
您可能拥有我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
代码.
我已经为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版本中修复的错误.