def func1():...def func2():...
funcmap ={1: func1,2: func2}def somefunc(a):
funcmap[a]()#Ugly! But it works.
Zugegeben, das ist nicht der beste Weg, um goto zu ersetzen. Aber ohne genau zu wissen, was Sie mit dem goto machen wollen, ist es schwierig, spezifische Ratschläge zu geben.
Am besten schließen Sie es entweder in eine Funktion ein oder verwenden eine Ausnahme. Für die Funktion:
def loopfunc():while1:while1:if condition:return
Für die Ausnahme:
try:while1:while1:raiseBreakoutException#Not a real exception, invent your ownexceptBreakoutException:pass
Die Verwendung von Ausnahmen für solche Aufgaben kann sich etwas unangenehm anfühlen, wenn Sie aus einer anderen Programmiersprache stammen. Aber ich würde argumentieren, dass Python nicht die Sprache für Sie ist, wenn Sie keine Ausnahmen verwenden möchten. :-)
Verwenden Sie es mit Bedacht. Ausnahmen in Python sind schneller als in den meisten anderen Sprachen. Aber sie sind immer noch langsam, wenn Sie verrückt nach ihnen werden.
Jason Baker
Nur ein Hinweis: Die loopfuncImplementierung erfordert im Allgemeinen Eingaben und etwas mehr Aufwand, ist aber in den meisten Fällen meiner Meinung nach der beste Weg.
from goto import with_goto
@with_gotodef range(start, stop):
i = start
result =[]
label .begin
if i == stop:
goto .end
result.append(i)
i +=1
goto .begin
label .end
return result
Ich bin mir nicht sicher, warum man so etwas machen möchte. Das heißt, ich meine es nicht zu ernst. Aber ich möchte darauf hinweisen, dass diese Art der Metaprogrammierung in Python tatsächlich möglich ist, zumindest in CPython und PyPy, und nicht nur durch den Missbrauch der Debugger-API wie dieser andere Typ . Sie müssen sich jedoch mit dem Bytecode herumschlagen.
Sie können Ausnahmen verwenden, um ein „strukturiertes Goto“ bereitzustellen, das sogar über Funktionsaufrufe hinweg funktioniert. Viele sind der Meinung, dass Ausnahmen alle vernünftigen Verwendungen der Konstrukte "go" oder "goto" von C, Fortran und anderen Sprachen bequem emulieren können. Beispielsweise:
class label(Exception):pass# declare a labeltry:...if condition:raise label()# goto label...except label:# where to gotopass...
Dies erlaubt Ihnen nicht, in die Mitte einer Schleife zu springen, aber das wird normalerweise sowieso als Missbrauch von goto angesehen. Sparsam verwenden.
Es ist sehr schön, dass dies sogar in den offiziellen FAQ erwähnt wird und dass ein schönes Lösungsbeispiel bereitgestellt wird. Ich mag Python wirklich, weil seine Community sogar gotoso behandelt ;)
@ B1KMusic: Der Einzug ist so wie er ist korrekt. Es ist eine spezielle Python-Syntax. elsewird nach der Schleife ausgeführt, wenn breaksie nicht gefunden wurde. Der Effekt ist , dass should_terminate_the_loopendet beide inneren und äußeren Schleifen.
JFS
1
Ich hätte angeben sollen, dass ich diese Entdeckung erst gemacht habe, nachdem ich die Bearbeitung vorgenommen habe. Vorher dachte ich, ich hätte einen Fehler im Interpreter entdeckt, also machte ich eine Reihe von Testfällen und recherchierte, um zu verstehen, was los war. Das tut mir leid.
Braden Best
1
Jetzt, da ich verstehe, was los ist, stimme ich zu, dass dies ein esoterischer Code ist, der mit traditionelleren Methoden
Braden Best
1
@ B1KMusic: Nein. Das Duplizieren von Code zur Umgehung Ihrer Unwissenheit ist keine gute Lösung. Ja. returnvorgeschlagen von @Jason Baker ist eine gute Alternative, um aus tief verschachtelten Schleifen auszubrechen.
Hinweis: Es wurde als Aprilscherz angeboten. (arbeitet aber)
# 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"
Unnötig zu erwähnen. Ja, es ist lustig, aber benutze es NICHT.
sieht für mich besser aus als 3 Pausen ... natürlich gibt es auch andere Möglichkeiten, es zu schreiben.
Nick
1
@Nick Die Verwendung der Funktion mit Rückgabe sieht noch viel besser aus.
Erik Šťastný
7
Etiketten für breakund continuewurden bereits 2007 in PEP 3136 vorgeschlagen , aber abgelehnt. Der Abschnitt Motivation des Vorschlags zeigt einige gängige (wenn auch unelegante) Methoden zur Nachahmung von breakin Python beschrifteten .
Es ist technisch machbar, Python mit etwas Arbeit eine 'goto'-ähnliche Anweisung hinzuzufügen. Wir werden die Module "dis" und "new" verwenden, die beide sehr nützlich sind, um Python-Byte-Code zu scannen und zu ändern.
Die Hauptidee hinter der Implementierung besteht darin, zunächst einen Codeblock mit den Anweisungen "goto" und "label" zu markieren. Ein spezieller "@goto" -Dekorator wird zum Markieren von "goto" -Funktionen verwendet. Anschließend scannen wir diesen Code nach diesen beiden Anweisungen und wenden die erforderlichen Änderungen auf den zugrunde liegenden Bytecode an. Dies alles geschieht zum Zeitpunkt der Kompilierung des Quellcodes.
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 gotoswhile 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 +=2continueif 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 jumpsfor label,index in gotos.items():if label notin labels:raiseException("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__':@gotodef 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 stuffif(condition(e)):
goto B_LOOP;
Mein Ansatz war es also, einen Booleschen Wert zu verwenden, um aus den verschachtelten for-Schleifen auszubrechen:
for a in xrange(1,10):
get_out =Falsefor b in xrange(1,5):if(get_out):breakfor c in xrange(1,5):if(get_out):breakfor d in xrange(1,5):# do some stuffif(condition(e)):
get_out =Truebreak
Ich wollte die gleiche Antwort und wollte sie nicht verwenden goto. Also habe ich das folgende Beispiel verwendet (von 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)
Anstelle eines Python-Goto-Äquivalents verwende ich die break-Anweisung folgendermaßen, um meinen Code schnell zu testen. Dies setzt voraus, dass Sie eine strukturierte Codebasis haben. Die Testvariable wird zu Beginn Ihrer Funktion initialisiert und ich verschiebe einfach den Block "If test: break" an das Ende des verschachtelten if-then-Blocks oder der verschachtelten Schleife, die ich testen möchte, und ändere die Rückgabevariable am Ende des Codes um die Block- oder Schleifenvariable wiederzugeben, die ich teste.
def x:
test =TrueIf y:# some codeIf test:breakreturn something
Obwohl es keinen Code gibt, der goto/labelPython entspricht, könnten Sie dennoch solche Funktionen für die goto/labelVerwendung von Schleifen erhalten.
Nehmen goto/labelwir ein unten gezeigtes Codebeispiel , das in einer anderen Sprache als Python verwendet werden kann.
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...')
Jetzt kann die gleiche Funktionalität des obigen Codebeispiels in Python mithilfe einer whileSchleife wie unten gezeigt erreicht werden.
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...')
Nein, es gibt eine alternative Möglichkeit, die goto-Anweisung zu implementieren
class id:def data1(self):
name=[]
age=[]
n=1while 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])breakexcept:print("list is empty")print("do want to continue y or n")
ch1=input()if ch1=="y":
n=n+1else:print("name \t age")for i in range(n):print(name[i]," \t ",age[i])
n=-1
p1=id()
p1.data1()
goto
in Python implementiert, als er Fortran-Code in Python übersetzte. Er hasste sich dafür.Antworten:
Nein, Python unterstützt keine Labels und goto, wenn Sie danach suchen. Es ist eine (stark) strukturierte Programmiersprache.
quelle
Python bietet Ihnen die Möglichkeit, einige der Dinge zu tun, die Sie mit einem goto mit erstklassigen Funktionen tun können. Beispielsweise:
Könnte in Python so gemacht werden:
Zugegeben, das ist nicht der beste Weg, um goto zu ersetzen. Aber ohne genau zu wissen, was Sie mit dem goto machen wollen, ist es schwierig, spezifische Ratschläge zu geben.
@ ascobol :
Am besten schließen Sie es entweder in eine Funktion ein oder verwenden eine Ausnahme. Für die Funktion:
Für die Ausnahme:
Die Verwendung von Ausnahmen für solche Aufgaben kann sich etwas unangenehm anfühlen, wenn Sie aus einer anderen Programmiersprache stammen. Aber ich würde argumentieren, dass Python nicht die Sprache für Sie ist, wenn Sie keine Ausnahmen verwenden möchten. :-)
quelle
loopfunc
Implementierung erfordert im Allgemeinen Eingaben und etwas mehr Aufwand, ist aber in den meisten Fällen meiner Meinung nach der beste Weg.Ich habe kürzlich einen Funktionsdekorator geschrieben , der
goto
in Python einfach Folgendes ermöglicht :Ich bin mir nicht sicher, warum man so etwas machen möchte. Das heißt, ich meine es nicht zu ernst. Aber ich möchte darauf hinweisen, dass diese Art der Metaprogrammierung in Python tatsächlich möglich ist, zumindest in CPython und PyPy, und nicht nur durch den Missbrauch der Debugger-API wie dieser andere Typ . Sie müssen sich jedoch mit dem Bytecode herumschlagen.
quelle
.begin
und.end
beschriftet dies nur ?Ich fand dies in den offiziellen Python Design and History FAQ .
Es ist sehr schön, dass dies sogar in den offiziellen FAQ erwähnt wird und dass ein schönes Lösungsbeispiel bereitgestellt wird. Ich mag Python wirklich, weil seine Community sogar
goto
so behandelt ;)quelle
So beantworten Sie die
@ascobol
Frage mit@bobince
dem Vorschlag aus den Kommentaren:Der Einzug für den
else
Block ist korrekt. Der Code verwendet obskurelse
nach einer Python-Schleifensyntax. Siehe Warum verwendet Python 'else' nach for- und while-Schleifen?quelle
else
wird nach der Schleife ausgeführt, wennbreak
sie nicht gefunden wurde. Der Effekt ist , dassshould_terminate_the_loop
endet beide inneren und äußeren Schleifen.return
vorgeschlagen von @Jason Baker ist eine gute Alternative, um aus tief verschachtelten Schleifen auszubrechen.Eine funktionierende Version wurde erstellt: http://entrian.com/goto/ .
Hinweis: Es wurde als Aprilscherz angeboten. (arbeitet aber)
Unnötig zu erwähnen. Ja, es ist lustig, aber benutze es NICHT.
quelle
Etiketten für
break
undcontinue
wurden bereits 2007 in PEP 3136 vorgeschlagen , aber abgelehnt. Der Abschnitt Motivation des Vorschlags zeigt einige gängige (wenn auch unelegante) Methoden zur Nachahmung vonbreak
in Python beschrifteten .quelle
Es ist technisch machbar, Python mit etwas Arbeit eine 'goto'-ähnliche Anweisung hinzuzufügen. Wir werden die Module "dis" und "new" verwenden, die beide sehr nützlich sind, um Python-Byte-Code zu scannen und zu ändern.
Die Hauptidee hinter der Implementierung besteht darin, zunächst einen Codeblock mit den Anweisungen "goto" und "label" zu markieren. Ein spezieller "@goto" -Dekorator wird zum Markieren von "goto" -Funktionen verwendet. Anschließend scannen wir diesen Code nach diesen beiden Anweisungen und wenden die erforderlichen Änderungen auf den zugrunde liegenden Bytecode an. Dies alles geschieht zum Zeitpunkt der Kompilierung des Quellcodes.
Hoffe das beantwortet die Frage.
quelle
Sie können benutzerdefinierte Ausnahmen zum Emulieren verwenden
goto
Beispiel:
quelle
Python 2 & 3
Link: goto-Anweisung
foo.py.
quelle
Ich suchte nach etwas Ähnlichem
Mein Ansatz war es also, einen Booleschen Wert zu verwenden, um aus den verschachtelten for-Schleifen auszubrechen:
quelle
Das gibt es jetzt. gehe zu
Ich denke, dies könnte nützlich sein für das, was Sie suchen.
quelle
Ich wollte die gleiche Antwort und wollte sie nicht verwenden
goto
. Also habe ich das folgende Beispiel verwendet (von learnpythonthehardway)quelle
Ich habe meine eigene Art, Gotos zu machen. Ich benutze separate Python-Skripte.
Wenn ich eine Schleife machen möchte:
file1.py
file2.py
file3.py
( HINWEIS: Diese Technik funktioniert nur in Python 2.x-Versionen.)
quelle
Für ein Forward Goto können Sie einfach hinzufügen:
Dies hilft jedoch nur bei einfachen Szenarien (dh wenn Sie diese verschachteln, geraten Sie in Unordnung).
quelle
Anstelle eines Python-Goto-Äquivalents verwende ich die break-Anweisung folgendermaßen, um meinen Code schnell zu testen. Dies setzt voraus, dass Sie eine strukturierte Codebasis haben. Die Testvariable wird zu Beginn Ihrer Funktion initialisiert und ich verschiebe einfach den Block "If test: break" an das Ende des verschachtelten if-then-Blocks oder der verschachtelten Schleife, die ich testen möchte, und ändere die Rückgabevariable am Ende des Codes um die Block- oder Schleifenvariable wiederzugeben, die ich teste.
quelle
Obwohl es keinen Code gibt, der
goto/label
Python entspricht, könnten Sie dennoch solche Funktionen für diegoto/label
Verwendung von Schleifen erhalten.Nehmen
goto/label
wir ein unten gezeigtes Codebeispiel , das in einer anderen Sprache als Python verwendet werden kann.Jetzt kann die gleiche Funktionalität des obigen Codebeispiels in Python mithilfe einer
while
Schleife wie unten gezeigt erreicht werden.quelle
Nein, es gibt eine alternative Möglichkeit, die goto-Anweisung zu implementieren
quelle