Is er een label/goto in Python?

Is er een gotoof een equivalent in Python om naar een specifieke regel code te kunnen springen?


Antwoord 1, autoriteit 100%

Nee, Python ondersteunt geen labels en goto, als dat is wat je zoekt. Het is een (zeer) gestructureerde programmeertaal.


Antwoord 2, autoriteit 63%

Python biedt je de mogelijkheid om een aantal dingen te doen die je zou kunnen doen met een goto met behulp van eersteklas functies. Bijvoorbeeld:

void somefunc(int a)
{
    if (a == 1)
        goto label1;
    if (a == 2)
        goto label2;
    label1:
        ...
    label2:
        ...
}

Kan als volgt in python worden gedaan:

def func1():
    ...
def func2():
    ...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
    funcmap[a]()  #Ugly!  But it works.

Toegegeven, dat is niet de beste manier om goto te vervangen. Maar zonder precies te weten wat je probeert te doen met de goto, is het moeilijk om specifiek advies te geven.

@ascobol:

U kunt het beste het insluiten in een functie of een uitzondering gebruiken. Voor de functie:

def loopfunc():
    while 1:
        while 1:
            if condition:
                return

Voor de uitzondering:

try:
    while 1:
        while 1:
            raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
    pass

Uitzonderingen gebruiken om dit soort dingen te doen, kan een beetje ongemakkelijk aanvoelen als je uit een andere programmeertaal komt. Maar ik zou zeggen dat als je een hekel hebt aan het gebruik van uitzonderingen, Python niet de taal voor jou is. 🙂


Antwoord 3, autoriteit 55%

Ik heb onlangs een functie-decorateurgeschreven die gotoin Python inschakelt, zomaar:

from goto import with_goto
@with_goto
def range(start, stop):
    i = start
    result = []
    label .begin
    if i == stop:
        goto .end
    result.append(i)
    i += 1
    goto .begin
    label .end
    return result

Ik weet echter niet zeker waarom iemand zoiets zou willen doen. Dat gezegd hebbende, ik ben er niet al te serieus over. Maar ik wil erop wijzen dat dit soort meta-programmering echt mogelijk is in Python, in ieder geval in CPython en PyPy, en niet alleen door misbruik te maken van de debugger-API zoals die andere manwel. Je moet wel met de bytecode knoeien.


Antwoord 4, autoriteit 27%

Ik vond dit in het officiële python-ontwerp en veelgestelde vragen over geschiedenis.

Waarom is er geen ga naar?

Je kunt uitzonderingen gebruiken om een “gestructureerde goto” te bieden die zelfs werkt
over functieaanroepen. Velen zijn van mening dat uitzonderingen gemakkelijk kunnen
emuleren alle redelijke gebruik van de “go” of “goto” constructies van C,
Fortran en andere talen. Bijvoorbeeld:

class label(Exception): pass  # declare a label
try:
    ...
    if condition: raise label()  # goto label
    ...
except label:  # where to goto
    pass
... 

Hiermee kun je niet in het midden van een lus springen, maar dat is
meestal beschouwd als een misbruik van goto toch. Spaarzaam gebruiken.

Het is heel fijn dat dit zelfs wordt vermeld in de officiële FAQ, en dat er een mooi voorbeeld van een oplossing wordt meegeleverd. Ik hou echt van python omdat de community zelfs gotozo behandelt 😉


Antwoord 5, autoriteit 11%

Om de vraag van @ascobolte beantwoorden met behulp van @bobince‘s suggestie uit de opmerkingen:

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

De inspringing voor het else-blok is correct. De code gebruikt obscure elsena een lus Python-syntaxis. Zie Waarom gebruikt python ‘else’ na for- en while-loops?


Antwoord 6, autoriteit 10%

Er is een werkende versie gemaakt: http://entrian.com/goto/.

Opmerking: het werd aangeboden als een 1-aprilgrap. (werkt wel)

# Example 1: Breaking out from a deeply nested loop:
from goto import goto, label
for i in range(1, 10):
    for j in range(1, 20):
        for k in range(1, 30):
            print i, j, k
            if k == 3:
                goto .end
label .end
print "Finished\n"

Onnodig te zeggen. Ja, het is grappig, maar gebruik het NIET.


Antwoord 7, autoriteit 8%

Het is technisch mogelijk om met wat werk een ‘goto’-achtige instructie aan python toe te voegen. We zullen de modules “dis” en “new” gebruiken, beide erg handig voor het scannen en wijzigen van python-bytecode.

Het belangrijkste idee achter de implementatie is om eerst een codeblok te markeren met ‘goto’- en ‘label’-instructies. Er wordt een speciale “@goto”-decorateur gebruikt om “goto”-functies te markeren. Daarna scannen we die code op deze twee statements en brengen we de nodige aanpassingen aan in de onderliggende bytecode. Dit gebeurt allemaal tijdens het compileren van de broncode.

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()

Ik hoop dat dit de vraag beantwoordt.


Antwoord 8, autoriteit 6%

Labels voor breaken continuewerden voorgesteld in PEP 3136in 2007, maar het werd afgewezen. Het gedeelte Motivatievan het voorstel illustreert verschillende veelvoorkomende (zij het onelegante) methoden voor het imiteren van het label breakin Python.


Antwoord 9, autoriteit 6%

Python 2 & 3

pip3 install goto-statement

getest op Python 2.6 tot en met 3,6 en PYPY.

Link: goto-statement


foo.py

from goto import with_goto
@with_goto
def bar():
    label .bar_begin
    ...
    goto .bar_begin

Antwoord 10, Autoriteit 5%

U kunt door de gebruiker gedefinieerde uitzonderingen to gebruiken emuleren goto

Voorbeeld:

class goto1(Exception):
    pass   
class goto2(Exception):
    pass   
class goto3(Exception):
    pass   
def loop():
    print 'start'
    num = input()
    try:
        if num<=0:
            raise goto1
        elif num<=2:
            raise goto2
        elif num<=4:
            raise goto3
        elif num<=6:
            raise goto1
        else:
            print 'end'
            return 0
    except goto1 as e:
        print 'goto1'
        loop()
    except goto2 as e:
        print 'goto2'
        loop()
    except goto3 as e:
        print 'goto3'
        loop()

Antwoord 11, Autoriteit 2%

Ik was op zoek naar iets dat lijkt op

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;

Dus mijn aanpak was om een boolean te gebruiken om uit de geneste for-lussen te komen:

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

Antwoord 12, autoriteit 2%

Hoewel er geen code is die equivalent is aan goto/labelin Python, zou je toch de functionaliteit van goto/labelkunnen krijgen met behulp van loops.

Laten we een codevoorbeeld nemen dat hieronder wordt weergegeven, waarbij goto/labelkan worden gebruikt in een willekeurige andere taal dan python.

String str1 = 'BACK'
label1:
    print('Hello, this program contains goto code\n')
    print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
    str1 = input()
if str1 == 'BACK'
    {
        GoTo label1
    }
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

Dezelfde functionaliteit van het bovenstaande codevoorbeeld kan nu worden bereikt in python door een while-lus te gebruiken, zoals hieronder weergegeven.

str1 = 'BACK'
while str1 == 'BACK':
        print('Hello, this is a python program containing python equivalent code for goto code\n')
        print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
        str1 = input()
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')

Antwoord 13

Er is nu. ga naar

Ik denk dat dit nuttig kan zijn voor wat u zoekt.


Antwoord 14

Ik wilde hetzelfde antwoord en ik wilde gotoniet gebruiken. Dus ik gebruikte het volgende voorbeeld (van 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)

Antwoord 15

Ik heb mijn eigen manier om gotos te doen.
Ik gebruik aparte python-scripts.

Als ik wil herhalen:

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")

(OPMERKING:deze techniek werkt alleen op Python 2.x-versies)


Antwoord 16

Voor een voorwaartse Ga naar, kunt u gewoon toevoegen:

while True:
  if some condition:
    break
  #... extra code
  break # force code to exit. Needed at end of while loop
#... continues here

Dit helpt echter alleen voor eenvoudige scenario’s (d.w.z. als u deze nesten zou u in de war raken)


Antwoord 17

In plaats van een python goto-equivalent gebruik ik de break-instructie op de volgende manier voor snelle tests van mijn code. Dit veronderstelt dat u een gestructureerde codebasis hebt. De testvariabele wordt aan het begin van uw functie geïnitialiseerd en ik verplaats gewoon het “If test: break” -blok naar het einde van het geneste if-then-blok of de lus die ik wil testen, waarbij ik de retourvariabele aan het einde van de code aanpas om de blok- of lusvariabele weer te geven die ik aan het testen ben.

def x:
  test = True
  If y:
     # some code
     If test:
            break
  return something

Antwoord 18

Je kunt dit bereiken met behulp van geneste methoden in python

def func1():
    print("inside func1")
    def inline():
        print("im inside")
    inline()
func1()

Antwoord 19

nee, er is een alternatieve manier om goto-statement te implementeren

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()  

Antwoord 20

Ik denk dat while-lus alternatief is voor de “goto_Statement”. Omdat na 3.6 goto loop niet meer werkt. Ik schrijf ook een voorbeeld van de while-lus.

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")    

Other episodes