Apakah ada goto
atau apapun yang setara dalam Python untuk dapat melompat ke baris tertentu dari code?
Python menawarkan anda kemampuan untuk melakukan beberapa hal yang bisa anda lakukan dengan goto menggunakan fungsi kelas pertama. Misalnya:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
Bisa dilakukan di python seperti ini:
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
Memang, yang isn't cara terbaik untuk pengganti goto. Tapi tanpa tahu persis apa yang anda're mencoba untuk melakukan dengan goto, it's sulit untuk memberikan saran khusus.
@ascobol:
Anda bertaruh terbaik adalah untuk menyertakan dalam fungsi atau gunakan pengecualian. Untuk fungsi:
def loopfunc():
while 1:
while 1:
if condition:
return
Untuk pengecualian:
try:
while 1:
while 1:
raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
pass
Menggunakan pengecualian untuk melakukan hal-hal seperti ini mungkin merasa sedikit canggung jika anda berasal dari bahasa pemrograman lain. Tapi saya berpendapat bahwa jika anda tidak suka menggunakan pengecualian, Python isn't bahasa untuk anda. :-)
Saya baru-baru ini menulis fungsi dekorator yang memungkinkan goto
di Python, seperti:
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
I'm tidak yakin mengapa ada orang yang ingin melakukan sesuatu seperti itu. Yang mengatakan, saya'm tidak terlalu serius tentang hal itu. Tapi aku'd ingin menunjukkan bahwa jenis meta pemrograman yang sebenarnya mungkin dalam Python, setidaknya di CPython dan Mount, dan tidak hanya dengan menyalahgunakan debugger API seperti yang orang lain lakukan. Anda harus main-main dengan bytecode sekalipun.
Saya menemukan ini di resmi python Desain dan Sejarah FAQ.
Mengapa tidak ada goto?
Anda dapat menggunakan pengecualian untuk memberikan "terstruktur goto" yang bahkan bekerja seluruh fungsi panggilan. Banyak yang merasa bahwa pengecualian mudah dapat meniru semua wajar menggunakan "go" atau "goto" konstruksi C, Fortran, dan bahasa-bahasa lain. Misalnya:
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
Ini tidak memungkinkan anda untuk melompat ke tengah-tengah lingkaran, tapi itu biasanya dianggap sebagai penyalahgunaan goto pula. Gunakan hemat.
It's sangat bagus yang ini bahkan disebutkan dalam resmi FAQ, dan bahwa solusi yang bagus sampel yang disediakan. Aku benar-benar seperti python karena masyarakat adalah mengobati bahkan goto
seperti ini ;)
Untuk menjawab @ascobol
's pertanyaan menggunakan @bobince
's saran dari komentar-komentar:
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
Indent untuk lain
block adalah benar. Kode menggunakan mengaburkan lagi
setelah loop sintaks Python. Lihat Mengapa python menggunakan 'lain' setelah untuk sementara loop?
Sebuah versi kerja yang telah dibuat: http://entrian.com/goto/.
Catatan: Itu ditawarkan sebagai April Mop's lelucon. (bekerja meskipun)
# 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"
Tak perlu dikatakan. Ya bentuknya yang lucu, tapi TIDAK menggunakannya.
Hal ini secara teknis layak untuk menambahkan 'goto' seperti pernyataan untuk python dengan beberapa pekerjaan. Kita akan gunakan "dis" dan "baru" modul, keduanya sangat berguna untuk memindai dan memodifikasi python kode byte.
Ide utama di balik pelaksanaan ini adalah untuk pertama menandai sebuah blok kode dengan menggunakan "goto" dan "label" pernyataan. Khusus "@goto" dekorator akan digunakan untuk tujuan penandaan "goto" fungsi. Setelah itu kita scan kode ini dua pernyataan dan menerapkan modifikasi yang diperlukan untuk mendasari kode byte. Ini semua terjadi pada source code waktu kompilasi.
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()
Semoga ini bisa menjawab pertanyaan.
anda dapat menggunakan User-defined Exception untuk meniru goto
contoh:
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()
Saya sedang mencari beberapa hal mirip dengan
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;
Jadi pendekatan saya untuk menggunakan boolean untuk membantu melanggar keluar dari nested loop:
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
Sekarang ada. goto
Saya pikir ini mungkin akan berguna untuk apa yang anda cari.
Aku ingin jawaban yang sama dan saya tidak ingin menggunakan goto
. Jadi saya menggunakan contoh berikut (dari 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)
Saya memiliki cara saya sendiri melakukan gotos. Aku terpisah menggunakan skrip python.
Jika saya ingin loop:
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")
(CATATAN: teknik Ini hanya bekerja pada Python versi 2.x versi)
Untuk ke depan Goto, anda bisa menambahkan:
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
Ini hanya membantu untuk skenario sederhana sekalipun (yaitu bersarang ini akan membuat anda menjadi berantakan)
Sebagai pengganti python goto setara saya menggunakan pernyataan break di fashion berikut untuk tes cepat dari kode saya. Ini mengasumsikan anda telah terstruktur basis kode. Uji variabel diinisialisasi pada awal fungsi anda dan saya hanya memindahkan "Jika tes: istirahat" blok untuk akhir nested blok if-then atau loop aku ingin menguji, memodifikasi kembali variabel pada akhir kode untuk mencerminkan blok atau variabel loop I'm pengujian.
def x:
test = True
If y:
# some code
If test:
break
return something
tidak ada cara alternatif untuk melaksanakan pernyataan 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()
pip3 install goto-statement
Diuji pada Python 2.6 melalui 3.6 dan Mount.
Link: goto-pernyataan
foo.py
from goto import with_goto
@with_goto
def bar(start, stop):
label .bar_begin
...
goto .bar_begin