为了账号安全,请及时绑定邮箱和手机立即绑定

在python中怎么实现goto功能?

/ 猿问

在python中怎么实现goto功能?

HUH函数 2019-02-21 19:15:42

假如:
#50# S3=...........(一个赋值行为)
#60# for............(这里有个三重循环)

##三重循环结束##

if ((L-1)==0):
L=0
goto 60
··else:
if (S3>S2):
goto 50

我要实现goto的功能,请问在不安装第三方库的前提下如何实现?

查看完整描述

3 回答

?
qq_遁去的一_1

使用如下例:

1 from goto import *
2
3 @patch
4 def f2():
5 goto(10)
6 print 'should not see this'
7 label(10)
8 for i in range(1,99999):
9 print i
10 if i == 5:
11 goto('out')
12 label('out')
13
14 f2()

用法是:

1. from goto import *。注意暂时不支持import goto,不是不能实现,是暂时没时间写。
2.对需要使用goto的函数,前面加个@patch
3.用label(x)和goto(x)的形式写label和goto。x可以是数字或字符串。

goto模块的代码如下:

goto.py



查看完整回答
反对 回复 2019-03-26
?
倚天杖

python有一个goto的库,你可以下源码了解一下。这里实在不方便发连接,在百度上搜“python goto”

原理是这样:通过给所有函数修改trace,然后在异常时就会执行设置的函数。

12345sys.settrace(_trace)frame = sys._getframe().f_backwhile frame:    frame.f_trace = _trace    frame = frame.f_back



查看完整回答
反对 回复 2019-03-26
?
手掌心

goto语句也称为无条件转移语句,其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。

用法是:

1. from goto import *。注意暂时不支持import goto,不是不能实现,是暂时没时间写。

2.对需要使用goto的函数,前面加个@patch

3.用label(x)和goto(x)的形式写label和goto。x可以是数字或字符串。

 goto模块的代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304import dis,pdb  #dummy functions serving as target of bytecode patching def goto(label):     pass  def label(label):     pass  # def decode_bytecode(fun):     """Input: a function        Ouput: a list of pairs (opcode, arguments)"""     = fun.func_code.co_code     = len(c)     = 0     while i < n:         op = c[i]         += 1         arguments = ""         if ord(op) >= dis.HAVE_ARGUMENT:             arguments = c[i : i+2]             += 2         yield (op, arguments)  def sample():     goto(200)     if 1 == 2:         sample()     else:         print 'sample'           def test_decode(fun):     for op,arg in decode_bytecode(fun):         if arg=='':             print dis.opname[ord(op)]         else:             print dis.opname[ord(op)] +' '+str(ord(arg[0]))+' '+str(ord(arg[1]))           def match_pattern(seq, i, p):     """     try to match pattern p to seq[i:], return None if match failed     seq: output of decode_bytecode     p -> [instr, instr, ...]     instr -> (opcode, arg, arg)      opcode is a opcode string     arg -> ''                        I don't give a damn about this arg     arg -> integer                   match arg with number     arg -> string                    the arg is key of the returned match dict from which the arg value can be extracted     arg -> lambda                    lambda is evaluated with the argument, false return means failed match     """     #pdb.set_trace()     = {}      for op, arg1, arg2 in p:         if i==len(seq):             return None                   if dis.opmap[op] != ord(seq[i][0]):             return None          if arg1 == '':             pass         else:             if seq[i][1== '': return None                           a1 = ord(seq[i][1][0])             if type(arg1) is str:                 m[arg1]=a1             elif type(arg1) is int:                 if arg1 != a1: return None             elif not arg1(a1):                 return None          #don't need arg2 in this program          i+=1                return m           def int_to_bytecode_arg(i):     return chr(i  % 256+\            chr(i // 256)  def patch(fun):     NOP = chr(dis.opmap['NOP'])     co = fun.func_code     old = list(decode_bytecode(fun))     new = [] #a list of characters           #mapping from label to bytecode offset     label_table={}     #if a goto(label) is seen but label is not seen     #record for the number the bytecode offset of the     #argument for JUMP_ABSOLUTE for later patching     goto_table={}      i=0     #pdb.set_trace()     while i<len(old):         m= match_pattern(old, i,                          [('LOAD_GLOBAL','fun_name',''),                           ('LOAD_CONST','label',''),                           ('CALL_FUNCTION',1,''),                           ('POP_TOP','','')])         if m:             stmt = co.co_names[m['fun_name']]             label = co.co_consts[m['label']]                       if   and stmt == 'goto':             # we have a goto statement             if label_table.has_key(label):                 arg = int_to_bytecode_arg(label_table[label])             else:                 arg = '\xff\xff'                 goto_table[label] =\                  goto_table.get(label, [])+[len(new)+1]             new += chr(dis.opmap['JUMP_ABSOLUTE'])             new += arg             #todo             #this is to maintain proper bytecode offset to             #source code line number mapping. A better way             #would be fixing the mapping instead of using             #placeholders             new += NOP*7             += 4         elif and stmt == 'label':             # we have a label statement             label_table[label]=len(new)             if goto_table.has_key(label):                 for offset in goto_table[label]:                     new[offset: offset+2]=int_to_bytecode_arg(len(new))                 del goto_table[label]             new += NOP*10             += 4         else:             # emit as-is              new += old[i][0#the opcode             new += old[i][1#its args if it has              += 1      if len(goto_table):         #todo: output line number         raise Exception('missing label')      import types     newcode = types.CodeType(co.co_argcount,                        co.co_nlocals,                        co.co_stacksize,                        co.co_flags,                        ''.join(new),                        co.co_consts,                        co.co_names,                        co.co_varnames,                        co.co_filename,                        co.co_name,                        co.co_firstlineno,                        co.co_lnotab)     return types.FunctionType(newcode,fun.func_globals)



查看完整回答
反对 回复 2019-03-26
  • 3 回答
  • 0 关注
  • 1410 浏览
我要回答

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信