在Python中是否有goto或任何等价的东西能够跳转到特定的代码行?


当前回答

不,有另一种方法来实现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 \t age")
                        for i in range(n):
                            print(name[i]," \t ",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 \t age")
                for i in range(n):
                    print(name[i]," \t ",age[i])
                n=-1
p1=id()
p1.data1()  

其他回答

早在2007年,PEP 3136就提出了中断和继续的标签,但被拒绝了。提案的动机部分说明了在Python中模仿带标签的break的几种常见方法(虽然不太优雅)。

使用评论中@bobince的建议来回答@ascobol的问题:

for i in range(5000):
    for j in range(3000):
        if should_terminate_the_loop:
           break
    else: 
        continue # no break encountered
    break

else块的缩进是正确的。代码在循环Python语法后使用模糊的else。参见为什么python在for和while循环之后使用'else' ?

我想要同样的答案,我不想使用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)

通过一些工作,在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()

希望这回答了问题。

我在找一些类似的东西

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