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


当前回答

我认为while循环是“goto_Statement”的替代。因为3.6之后,goto循环不再工作了。我还写了一个while循环的例子。

str1 = "stop"
while str1 == "back":
    var1 = int(input(" Enter Ist Number: "))
    var2 = int(input(" Enter 2nd Number: "))
    var3 = print("""  What is your next operation
                      For Addition   Press And Enter : 'A'
                      For Muliplt    Press And Enter : 'M'
                      For Division   Press And Enter : 'D'
                      For Subtaction Press And Enter : 'S' """)

    var4 = str(input("For operation press any number : "))
    if(var1 == 45) and (var2 == 3):
        print("555")
    elif(var1 == 56) and (var2 == 9):
        print("77")
    elif(var1 == 56) and (var2 == 6):
        print("4")
    else:
        if(var4 == "A" or "a"):
            print(var1 + var2)
        if(var4 == "M" or "m"):
            print(var1 * var2)
        if(var4 == "D" or "d"):
            print(var1 / var2)
        if(var4 == "S" or "s"):
            print(var1 - var2)

    print("if you want to continue then type  'stop'")

    str1 = input()
print("Strt again")    

其他回答

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

希望这回答了问题。

我用函数解决了这个问题。我唯一做的就是改变函数的标签。下面是一个非常基本的代码:

def goto_holiday(): #label: holiday
        print("I went to holiday :)")
    
def goto_work(): #label: work
    print("I went to work")
salary=5000
if salary>6000:
    goto_holiday()
else:
    goto_work()

我认为while循环是“goto_Statement”的替代。因为3.6之后,goto循环不再工作了。我还写了一个while循环的例子。

str1 = "stop"
while str1 == "back":
    var1 = int(input(" Enter Ist Number: "))
    var2 = int(input(" Enter 2nd Number: "))
    var3 = print("""  What is your next operation
                      For Addition   Press And Enter : 'A'
                      For Muliplt    Press And Enter : 'M'
                      For Division   Press And Enter : 'D'
                      For Subtaction Press And Enter : 'S' """)

    var4 = str(input("For operation press any number : "))
    if(var1 == 45) and (var2 == 3):
        print("555")
    elif(var1 == 56) and (var2 == 9):
        print("77")
    elif(var1 == 56) and (var2 == 6):
        print("4")
    else:
        if(var4 == "A" or "a"):
            print(var1 + var2)
        if(var4 == "M" or "m"):
            print(var1 * var2)
        if(var4 == "D" or "d"):
            print(var1 / var2)
        if(var4 == "S" or "s"):
            print(var1 - var2)

    print("if you want to continue then type  'stop'")

    str1 = input()
print("Strt again")    

在执行“goto”时,首先必须问“goto”是什么。虽然看起来很明显,但大多数人都没有考虑goto与函数栈之间的关系。

如果在函数内部执行“goto”,实际上就放弃了函数调用堆栈。这被认为是一种糟糕的做法,因为函数栈的设计期望在委托一个中间任务之后,您将继续您离开的地方。这就是为什么goto用于异常,而异常可以用来模拟goto,我将对此进行解释。

Finite state machines are probably the best use case for goto, which most of the time are implemented in a kludgy way with loops and switch statements, but I believe that "top level" gotos, are the cleanest, most semantic way to implement finite state machines. In this case, you want to make sure, if you have more variables, they are globals, and don't require encapsulation. Make sure you first model your variable state space(which may be different from execution state, ie the finite state machine).

我相信有合理的设计理由使用goto,异常处理是特殊情况下,混合goto和函数是有意义的。然而,在大多数情况下,您希望将自己限制在“顶级”goto,因此永远不要在函数中调用goto,而只在全局作用域中调用。

在现代语言中模拟顶级goto最简单的方法是实现顶级goto只需要全局变量和空调用堆栈。因此,为了保持调用堆栈为空,每当调用新函数时都返回。下面是一个输出前n个斐波那契数的例子:

a = 0
b = 1
n = 100
def A():
    global a, b
    a = a + b
    n -= 1
    print(a)
    return B() if n > 0 else 0
def B():
    global a, b
    b = a + b
    n -= 1
    print(b)
    return A() if n > 0 else 0
A()

虽然这个示例可能比循环实现更详细,但它也更强大和灵活,并且不需要特殊情况。它让你有一个完整的有限状态机。您还可以使用goto运行器对此进行修改。

def goto(target):
    while(target) target = target()
def A():
    global a, b
    a = a + b
    print(a)
    return B
def B():
    global a, b
    b = a + b
    print(b)
    return A
goto(A)

为了强制执行“返回”部分,您可以编写一个goto函数,在完成时抛出一个异常。

def goto(target):
    target()
    throw ArgumentError("goto finished.")
def A():
    global a, b
    a = a + b
    print(a)
    goto(B)
def B()
    global a, b
    b = a + b
    print(b)
    goto(A)
goto(A)

因此,您可以看到,这在很大程度上是过度思考的,而调用一个函数然后抛出一个错误的helper函数就是您所需要的。您可以将它进一步包装在一个“start”函数中,这样错误就会被捕获,但我认为这并不是严格必要的。虽然其中一些实现可能会耗尽调用堆栈,但第一个运行器示例将其保持为空,如果编译器可以进行尾部调用优化,这也会有所帮助。

我有自己的做法。 我使用单独的python脚本。

如果我想要循环:

file1.py

print("test test")
execfile("file2.py")
a = a + 1

file2.py

print(a)
if a == 10:
   execfile("file3.py")
else:
   execfile("file1.py")

file3.py

print(a + " equals 10")

(注意:此技术仅适用于Python 2。x版本)