Apakah ada goto
atau yang setara dengan Python untuk dapat melompat ke baris kode tertentu?
goto
dalam Python ketika dia menerjemahkan beberapa kode Fortran ke Python. Dia membenci dirinya sendiri untuk itu.
Apakah ada goto
atau yang setara dengan Python untuk dapat melompat ke baris kode tertentu?
goto
dalam Python ketika dia menerjemahkan beberapa kode Fortran ke Python. Dia membenci dirinya sendiri untuk itu.
Jawaban:
Tidak, Python tidak mendukung label dan goto, jika itu yang Anda cari. Ini adalah bahasa pemrograman (sangat) terstruktur.
Python menawarkan Anda kemampuan untuk melakukan beberapa hal yang bisa Anda lakukan dengan goto menggunakan fungsi kelas satu. Sebagai contoh:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
Bisa dilakukan dengan python seperti ini:
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
Memang, itu bukan cara terbaik untuk menggantikan goto. Tetapi tanpa tahu persis apa yang Anda coba lakukan dengan kebagian, sulit untuk memberikan saran khusus.
@ ascobol :
Taruhan terbaik Anda adalah dengan melampirkannya dalam suatu fungsi atau menggunakan pengecualian. Untuk fungsi:
def loopfunc():
while 1:
while 1:
if condition:
return
Sebagai 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 terasa sedikit canggung jika Anda berasal dari bahasa pemrograman lain. Tapi saya berpendapat bahwa jika Anda tidak suka menggunakan pengecualian, Python bukan bahasa untuk Anda. :-)
loopfunc
umumnya akan membutuhkan input dan beberapa upaya lagi untuk diterapkan, tetapi itu adalah cara terbaik dalam banyak kasus saya pikir.
Baru-baru ini saya menulis dekorator fungsi yang memungkinkan goto
dengan Python, seperti itu:
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
Saya tidak yakin mengapa seseorang ingin melakukan sesuatu seperti itu. Yang mengatakan, saya tidak terlalu serius tentang itu. Tapi saya ingin menunjukkan bahwa pemrograman meta semacam ini sebenarnya mungkin dalam Python, setidaknya dalam CPython dan PyPy, dan tidak hanya dengan menyalahgunakan API debugger seperti yang dilakukan orang lain . Anda harus mengacaukan bytecode.
.begin
dan .end
memberi label?
Saya menemukan ini di FAQ Desain dan Sejarah python resmi .
Kenapa tidak ada goto?
Anda dapat menggunakan pengecualian untuk memberikan "goto terstruktur" yang bahkan berfungsi lintas panggilan fungsi. Banyak yang merasa bahwa pengecualian dapat dengan mudah meniru semua penggunaan yang masuk akal dari konstruksi “go” atau “goto” dari bahasa C, Fortran, dan lainnya. Sebagai contoh:
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 lingkaran, tetapi itu biasanya dianggap sebagai penyalahgunaan goto. Gunakan hemat.
Sangat menyenangkan bahwa ini bahkan disebutkan dalam FAQ resmi, dan bahwa sampel solusi yang bagus disediakan. Saya sangat suka python karena komunitasnya memperlakukan bahkan goto
seperti ini;)
goto
adalah pemrograman utama yang pasti, tetapi pengecualian menyalahgunakan IMO untuk ditiru goto
hanya sedikit lebih baik dan masih harus sangat disukai. Saya lebih suka pencipta Python memasukkan goto
dalam bahasa untuk beberapa kesempatan di mana itu sebenarnya berguna daripada melarangnya karena "itu buruk, teman-teman" dan kemudian merekomendasikan pengecualian yang menyalahgunakan untuk mendapatkan fungsi yang sama (dan spagettifikasi kode yang sama).
Untuk menjawab @ascobol
pertanyaan menggunakan @bobince
saran dari komentar:
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
Indentasi untuk else
blok sudah benar. Kode menggunakan tidak jelas else
setelah sintaks Python loop. Lihat Mengapa python menggunakan 'else' setelah untuk dan sementara loop?
else
dieksekusi setelah loop jika break
belum ditemukan. Efeknya adalah bahwa should_terminate_the_loop
berakhir baik loop dalam dan luar.
return
disarankan oleh @Jason Baker adalah alternatif yang baik untuk keluar dari loop yang sangat bersarang.
Versi yang berfungsi telah dibuat: http://entrian.com/goto/ .
Catatan: Itu ditawarkan sebagai lelucon April Mop. (meskipun bekerja)
# 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 itu lucu, tapi JANGAN menggunakannya.
Secara teknis layak untuk menambahkan pernyataan seperti 'goto' ke python dengan beberapa pekerjaan. Kami akan menggunakan modul "dis" dan "baru", keduanya sangat berguna untuk memindai dan memodifikasi kode byte python.
Gagasan utama di balik implementasi ini adalah untuk pertama menandai blok kode sebagai menggunakan pernyataan "goto" dan "label". Dekorator "@ goto" khusus akan digunakan untuk tujuan menandai fungsi "goto". Setelah itu kami memindai kode itu untuk kedua pernyataan ini dan menerapkan modifikasi yang diperlukan untuk kode byte yang mendasarinya. Ini semua terjadi pada waktu kompilasi kode sumber.
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 menjawab pertanyaan.
Anda dapat menggunakan Pengecualian Buatan Pengguna Buatan untuk menirugoto
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()
pip3 install goto-statement
Diuji pada Python 2.6 hingga 3.6 dan PyPy.
Tautan: pernyataan-goto
foo.py
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
Saya mencari sesuatu yang mirip
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 adalah menggunakan boolean untuk membantu keluar dari sarang untuk 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
Saya menginginkan jawaban yang sama dan saya tidak ingin menggunakannya 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 punya cara sendiri dalam melakukan goto. Saya menggunakan skrip python terpisah.
Jika saya ingin mengulang:
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 berfungsi pada versi Python 2.x)
Sebagai pengganti python goto equivalent saya menggunakan pernyataan break dengan cara berikut untuk tes cepat kode saya. Ini mengasumsikan Anda memiliki basis kode terstruktur. Variabel tes diinisialisasi pada awal fungsi Anda dan saya hanya memindahkan blok "If test: break" ke akhir blok if-then bersarang atau loop yang ingin saya uji, memodifikasi variabel kembali di akhir kode untuk mencerminkan variabel blok atau loop yang saya uji.
def x:
test = True
If y:
# some code
If test:
break
return something
Meskipun tidak ada kode yang setara dengan goto/label
Python, Anda masih bisa mendapatkan fungsionalitas goto/label
menggunakan loop.
Mari kita ambil contoh kode yang ditunjukkan di bawah ini di mana goto/label
dapat digunakan dalam bahasa arbitrer selain 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...')
Sekarang fungsi yang sama dari contoh kode di atas dapat dicapai dengan python dengan menggunakan while
loop seperti yang ditunjukkan di bawah ini.
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...')
tidak ada cara alternatif untuk mengimplementasikan 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()