goto
Python มีหรือเทียบเท่าใน Python เพื่อให้สามารถข้ามไปยังบรรทัดของรหัสที่ระบุได้หรือไม่?
goto
ใน Python เมื่อเขาแปลรหัส Fortran ไปเป็น Python เขาเกลียดตัวเอง
goto
Python มีหรือเทียบเท่าใน Python เพื่อให้สามารถข้ามไปยังบรรทัดของรหัสที่ระบุได้หรือไม่?
goto
ใน Python เมื่อเขาแปลรหัส Fortran ไปเป็น Python เขาเกลียดตัวเอง
คำตอบ:
ไม่ Python ไม่รองรับฉลากและข้ามไปหากเป็นสิ่งที่คุณต้องการ มันเป็นภาษาการเขียนโปรแกรมที่มีโครงสร้างสูง
Python เสนอความสามารถในการทำบางสิ่งที่คุณสามารถทำได้ด้วยการข้ามไปใช้ฟังก์ชั่นชั้นหนึ่ง ตัวอย่างเช่น:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
สามารถทำได้ใน python ดังนี้
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
ได้รับนั่นไม่ใช่วิธีที่ดีที่สุดในการทดแทนโกโตะ แต่ถ้าไม่รู้ว่าคุณกำลังพยายามทำอะไรกับ goto นั้นยากที่จะให้คำแนะนำเฉพาะ
@ ascobol :
ทางออกที่ดีที่สุดของคุณคือการปิดล้อมในฟังก์ชั่นหรือใช้ข้อยกเว้น สำหรับฟังก์ชั่น:
def loopfunc():
while 1:
while 1:
if condition:
return
สำหรับข้อยกเว้น:
try:
while 1:
while 1:
raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
pass
การใช้ข้อยกเว้นในการทำสิ่งต่าง ๆ เช่นนี้อาจรู้สึกอึดอัดใจเล็กน้อยหากคุณมาจากภาษาโปรแกรมอื่น แต่ฉันจะเถียงว่าถ้าคุณไม่ชอบการใช้ข้อยกเว้น Python ไม่ใช่ภาษาสำหรับคุณ :-)
loopfunc
โดยทั่วไปจะต้องมีปัจจัยการผลิตและความพยายามที่จะใช้มากขึ้น แต่มันเป็นวิธีที่ดีที่สุดในกรณีส่วนใหญ่ฉันคิดว่า
ฉันเพิ่ง เขียนมัณฑนากรฟังก์ชั่นที่เปิดใช้งานgoto
ใน Python แบบนั้น
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
ฉันไม่แน่ใจว่าทำไมคนเราถึงอยากทำอะไรแบบนั้น ที่กล่าวว่าฉันไม่จริงจังกับมัน แต่ผมอยากจะชี้ให้เห็นว่าชนิดของการเขียนโปรแกรมเมตานี้เป็นจริงที่เป็นไปได้ในหลามอย่างน้อยใน CPython และ PyPy และไม่เพียง แต่โดย misusing ดีบัก API กับที่คนอื่นทำ คุณต้องยุ่งกับ bytecode ว่า
.begin
และติด.end
ป้ายกำกับเท่านั้นหรือไม่
ฉันพบนี้ในหลามอย่างเป็นทางการออกแบบและประวัติศาสตร์คำถามที่พบบ่อย
ทำไมถึงไม่มี goto?
คุณสามารถใช้ข้อยกเว้นเพื่อจัดทำ "goto goto โครงสร้าง" ที่แม้ทำงานผ่านการเรียกใช้ฟังก์ชัน หลายคนรู้สึกว่าข้อยกเว้นสามารถเลียนแบบการใช้งานที่สมเหตุสมผลทั้งหมดของโครงสร้าง "go" หรือ "goto" ของ C, Fortran และภาษาอื่น ๆ ตัวอย่างเช่น:
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
สิ่งนี้ไม่อนุญาตให้คุณกระโดดเข้าไปกลางวง แต่โดยปกติแล้วถือว่าเป็นการละเมิดของ goto อยู่ดี ใช้เท่าที่จำเป็น
เป็นเรื่องที่ดีมากที่มีการกล่าวถึงใน FAQ อย่างเป็นทางการและมีตัวอย่างโซลูชันที่ดี ฉันชอบงูใหญ่เพราะชุมชนนั้นปฏิบัติต่อกันgoto
เช่นนี้;)
goto
วิธีเป็นโปรแกรมหลักที่ต้องแน่ใจ แต่ IMO ที่ใช้การยกเว้นเพื่อเลียนแบบgoto
นั้นดีกว่าเล็กน้อยและควรจะขมวดคิ้วอย่างหนัก ฉันอยากให้ผู้สร้าง Python รวมgoto
อยู่ในภาษาในบางครั้งที่มันมีประโยชน์มากกว่าที่จะไม่อนุญาตเพราะ "แย่มาก ๆ " แล้วแนะนำให้ใช้ข้อยกเว้นที่ไม่เหมาะสมเพื่อให้ได้ฟังก์ชันการทำงานเดียวกัน
ในการตอบ@ascobol
คำถามโดยใช้@bobince
คำแนะนำจากความคิดเห็น:
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
เยื้องสำหรับelse
บล็อกถูกต้อง รหัสใช้คลุมเครือelse
หลังจากวนลูปไวยากรณ์ ดูทำไมงูหลามจึงใช้ 'else' หลังจากนั้นและในขณะที่ลูป
else
ถูกดำเนินการหลังจากวนรอบหากbreak
ไม่พบ ผลที่ได้คือshould_terminate_the_loop
ยุติทั้งด้านในและด้านนอกของลูป
return
แนะนำโดย @Jason Bakerเป็นทางเลือกที่ดีในการแยกลูปที่ซ้อนกันอย่างล้ำลึก
รุ่นที่ทำงานได้รับการทำ: http://entrian.com/goto/
หมายเหตุ: มันเป็นเรื่องตลกของ April Fool (ทำงานแม้ว่า)
# 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"
จำเป็นต้องพูด ใช่มันตลก แต่ไม่ได้ใช้
ป้ายกำกับbreak
และcontinue
ถูกเสนอในPEP 3136ย้อนกลับไปในปี 2550 แต่ถูกปฏิเสธ แรงจูงใจในส่วนของข้อเสนอแสดงให้เห็นถึงพื้นฐานหลายประการ (ถ้าไม่งดงาม) วิธีการเลียนแบบที่มีข้อความbreak
ในหลาม
มีความเป็นไปได้ทางเทคนิคที่จะเพิ่มคำสั่ง like 'goto' ใน python กับงานบางอย่าง เราจะใช้โมดูล "dis" และ "new" ซึ่งมีประโยชน์อย่างมากสำหรับการสแกนและการแก้ไขโค้ดไบต์หลาม
แนวคิดหลักที่อยู่เบื้องหลังการใช้งานคือการทำเครื่องหมายบล็อกของรหัสก่อนโดยใช้คำสั่ง "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()
หวังว่านี้จะตอบคำถาม
คุณสามารถใช้ข้อยกเว้นที่ผู้ใช้กำหนดเพื่อเลียนแบบgoto
ตัวอย่าง:
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
ทดสอบกับ Python 2.6 ถึง 3.6 และ PyPy
Link: goto-statement
foo.py
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
ฉันกำลังมองหาบางสิ่งที่คล้ายกับ
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;
ดังนั้นวิธีการของฉันคือใช้บูลีนเพื่อช่วยแยกออกจากรังสำหรับลูป:
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
ตอนนี้มี ไปที่
ฉันคิดว่านี่อาจเป็นประโยชน์สำหรับสิ่งที่คุณกำลังมองหา
goto
ฉันต้องการคำตอบเดียวกันและผมไม่ต้องการที่จะใช้ ดังนั้นฉันใช้ตัวอย่างต่อไปนี้ (จาก 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)
ฉันมีวิธีทำ gotos ของตัวเอง ฉันใช้สคริปต์หลามแยกต่างหาก
ถ้าฉันต้องการวนรอบ:
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 เท่านั้น)
สำหรับไปข้างหน้าคุณสามารถเพิ่ม:
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
สิ่งนี้จะช่วยในสถานการณ์ง่าย ๆ เท่านั้น (เช่นการซ้อนสิ่งเหล่านี้จะทำให้คุณสับสน)
แทนที่จะใช้ python goto ที่เทียบเท่าฉันใช้คำสั่ง break ในแบบต่อไปนี้สำหรับการทดสอบโค้ดอย่างรวดเร็ว สิ่งนี้จะถือว่าคุณมีฐานรหัสที่มีโครงสร้าง ตัวแปรทดสอบเริ่มต้นได้ที่จุดเริ่มต้นของฟังก์ชั่นของคุณและฉันเพิ่งย้ายบล็อก "If test: break" ไปยังจุดสิ้นสุดของ if-then block หรือ loop ที่ฉันต้องการทดสอบปรับเปลี่ยนตัวแปร return ที่ท้ายรหัส เพื่อสะท้อนถึงบล็อกหรือตัวแปรลูปฉันกำลังทดสอบ
def x:
test = True
If y:
# some code
If test:
break
return something
แม้ว่าจะไม่มีรหัสใดเทียบเท่ากับgoto/label
ใน Python คุณยังสามารถรับฟังก์ชั่นดังกล่าวได้goto/label
ใช้ใช้ลูปได้
ให้นำตัวอย่างโค้ดที่แสดงด้านล่างซึ่งgoto/label
สามารถใช้ในภาษาใดก็ได้ที่ไม่ใช่ภาษาไพ ธ อน
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...')
ตอนนี้การทำงานที่เหมือนกันของตัวอย่างโค้ดข้างต้นสามารถทำได้ในไพ ธ อนโดยใช้การwhile
วนซ้ำตามที่แสดงด้านล่าง
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...')
ไม่มีวิธีอื่นในการใช้คำสั่ง 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()