Python에 라벨/goto가 있나요?
goto아니면 Python에서 특정 코드 행으로 점프할 수 있는 동등한 코드라도 있나요?
아니요, Python은 라벨과 goto를 지원하지 않습니다.그것은 고도로 구조화된 프로그래밍 언어입니다.
Python은 퍼스트 클래스 기능을 사용하여 goto로 할 수 있는 몇 가지 기능을 제공합니다.예를 들어 다음과 같습니다.
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.
그래, 그건 고토를 대신할 수 있는 최선의 방법이 아니야.하지만 당신이 그 고토를 가지고 무엇을 하려고 하는지 정확히 알지 못한다면, 구체적인 조언을 해주기는 어렵습니다.
@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은 당신에게 맞는 언어가 아닙니다. :-)
제가 최근에 쓴 기능성 데코레이터는goto파이썬
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에서, 그리고 다른 사람이 했던 것처럼 디버거 API를 잘못 사용함으로써만 가능한 것이 아니라는 것을 지적하고 싶습니다.그런데 바이트 코드를 망치셔야 해요.
공식 python Design and History FAQ에서 찾았습니다.
왜 goto가 없는거죠?
예외를 사용하여 함수 호출 간에 작동하는 "구조화된 goto"를 제공할 수 있습니다.많은 사람들은 예외가 C, Fortran 및 기타 언어의 "go" 또는 "goto" 구조의 모든 합리적인 사용을 편리하게 에뮬레이트할 수 있다고 생각합니다.예를 들어 다음과 같습니다.
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
루프 한가운데로 뛰어드는 것은 허용되지 않지만, 어쨌든 그건 보통 goto의 남용으로 간주됩니다.적게 사용하세요.
공식 FAQ에도 언급되어 있고, 좋은 솔루션 샘플이 제공되어 매우 기쁩니다. 대접하고 에 비단뱀을 .goto 식으로
동작하는 버전이 작성되었습니다.http://entrian.com/goto/
메모: 그것은 만우절 농담으로 제공되었다.(단, 동작 중)
# 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"
그렇게까지 말하지 않아도.네, 재미있지만 사용하지 마세요.
의 질문에 답하려면@bobince님의 코멘트에서 제안하는 것은 다음과 같습니다.
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
「 」의 .else블록은 정확합니다.에는 모호한 코드인 '모호한 코드'가 되고 있습니다.elsePython 구문을 루프한 후에.자세한 내용은 python이 루프에 대해 'else'를 사용하는 이유를 참조하십시오.
기술적으로 python에 goto와 같은 문을 추가하는 것은 가능하다."dis" 및 "new" 모듈을 사용하여 python 바이트 코드를 스캔하고 수정하는 데 매우 유용합니다.
구현 이면의 주요 아이디어는 먼저 코드 블록을 "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()
이게 질문에 대한 해답이길 바랍니다.
Python 2 & 3
pip3 install goto-statement
Python 2.6~3.6 및 PyPy에서 테스트 완료.
링크: goto-statement
foo.py
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
의 break ★★★★★★★★★★★★★★★★★」continue2007년에 PEP 3136에서 제안되었지만 거부되었습니다.제안서의 '동기 부여' 섹션은 라벨 부착을 모방하기 위한 몇 가지 일반적인(미숙하지만) 방법을 보여줍니다.breakPython 서 python 。
사용자 정의 예외를 사용하여 에뮬레이트할 수 있습니다.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()
비슷한 걸 찾고 있었어요
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
ententent에 해당하는 코드는 없습니다.에 해당하는 는 없습니다.goto/labelPython의 기능을 할 수 .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...')
에서도 python을 할 수 .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...')
python 내부에 중첩된 메서드를 사용하여 달성할 수 있습니다.
def func1():
print("inside func1")
def inline():
print("im inside")
inline()
func1()
지금 있다. goto
이것은 당신이 찾고 있는 것에 도움이 될 것 같습니다.
goto를 구현하려면 먼저 goto가 무엇인지 물어봐야 합니다.분명해 보이지만 대부분의 사람들은 goto와 함수 스택의 관계에 대해 생각하지 않습니다.
함수 내에서 "goto"를 실행하면 사실상 함수 콜스택이 포기됩니다.함수 스택은 중간 작업을 위임한 후 중단한 위치에서 계속 진행되도록 설계되기 때문에 이는 잘못된 관행으로 간주됩니다.그렇기 때문에 예외로 goto를 사용하고, 예외로 goto를 모방할 수 있습니다.
유한 상태 머신은 아마도 goto에 가장 적합한 사용 사례일 것입니다. goto는 대부분의 경우 루프와 스위치 스테이트먼트를 사용하여 kludy 방식으로 구현되지만, 저는 "top level" goto가 유한 상태 머신을 구현하기 위한 가장 깨끗하고 의미 있는 방법이라고 생각합니다.이 경우 변수가 더 많을 경우 해당 변수가 글로벌이며 캡슐화가 필요하지 않음을 확인해야 합니다.먼저 가변 상태 공간(실행 상태, 즉 유한 상태 시스템과 다를 수 있음)을 모델링하십시오.
goto를 사용하는 것은 정당한 디자인상의 이유가 있다고 생각합니다만, 예외 처리는 goto와 기능을 혼합하는 것이 의미가 있는 특수한 경우입니다.다만, 대부분의 경우, 「최상위 레벨」의 goto에 한정하고 싶기 때문에, 함수내에서 goto를 호출하는 것은 아니고, 글로벌한 범위내에서만 행해집니다.
현대 언어에서 최상위 goto를 에뮬레이트하는 가장 쉬운 방법은 최상위 goto가 단순히 글로벌 변수와 빈 콜 스택을 필요로 한다는 것을 깨닫는 것입니다.따라서 콜 스택을 비워두기 위해 새로운 함수를 호출할 때마다 돌아갑니다.다음으로 첫 번째 n개의 fibonacci 번호를 인쇄하는 예를 나타냅니다.
a = 0
b = 1
n = 100
def A():
global a, b
a = a + b
n -= 1
print(a)
return B() if n > 0 else 0
def B():
global a, b
b = a + b
n -= 1
print(b)
return A() if n > 0 else 0
A()
이 예는 루프 실장보다 상세하게 설명될 수 있지만 훨씬 강력하고 유연하며 특별한 경우가 필요하지 않습니다.완전 유한 상태 머신을 사용할 수 있습니다.goto runner를 사용하여 수정할 수도 있습니다.
def goto(target):
while(target) target = target()
def A():
global a, b
a = a + b
print(a)
return B
def B():
global a, b
b = a + b
print(b)
return A
goto(A)
"return" 부분을 적용하기 위해 종료 시 예외를 발생시키는 goto 함수를 작성할 수 있습니다.
def goto(target):
target()
throw ArgumentError("goto finished.")
def A():
global a, b
a = a + b
print(a)
goto(B)
def B()
global a, b
b = a + b
print(b)
goto(A)
goto(A)
보시다시피, 많은 부분이 너무 많이 고려되고 있습니다. 함수를 호출하고 오류를 발생시키는 도우미 기능만 있으면 됩니다.에러가 잡힐 수 있도록, 「시작」기능으로 한층 더 포장할 수도 있습니다만, 꼭 그럴 필요는 없다고 생각합니다.이러한 실장 중 일부는 콜스택을 다 사용하는 경우가 있습니다만, 첫 번째 실행 예에서는 콜스택을 비워 두고 컴파일러가 테일콜 최적화를 실행할 수 있는 경우에도 도움이 됩니다.
나는 같은 대답을 원했고 그것을 사용하고 싶지 않았다.goto그래서 저는 (hardway의 learnpyththan에서) 다음 예를 사용했습니다.
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)
나는 나만의 방법이 있다.python 스크립트를 따로 사용합니다.
루프할 경우:
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 버전에서만 작동합니다.)
Forward Goto의 경우 다음과 같이 추가할 수 있습니다.
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 또는 루프의 끝으로 이동하여 테스트 중인 블록 또는 루프 변수를 반영하도록 코드 끝에 있는 반환 변수를 수정합니다.
def x:
test = True
If y:
# some code
If test:
break
return something
아니요, 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()
루프는 'goto_Statement'의 대체 수단이라고 생각합니다.왜냐하면 3.6 이후 goto loop은 더 이상 작동하지 않기 때문입니다.while loop의 예도 씁니다.
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")
저는 이 문제를 기능으로 해결했습니다.제가 한 것은 기능 라벨 변경뿐입니다.다음은 매우 기본적인 코드입니다.
def goto_holiday(): #label: holiday
print("I went to holiday :)")
def goto_work(): #label: work
print("I went to work")
salary=5000
if salary>6000:
goto_holiday()
else:
goto_work()
언급URL : https://stackoverflow.com/questions/438844/is-there-a-label-goto-in-python
'programing' 카테고리의 다른 글
| print_r 결과를 문자열 또는 텍스트로 변수에 저장합니다. (0) | 2022.09.24 |
|---|---|
| PHP에서 MySQL 테이블의 마지막 삽입 ID를 얻으려면 어떻게 해야 하나요? (0) | 2022.09.24 |
| Python에서 일반적인 bash idiod를 구현하려면 어떻게 해야 합니까? (0) | 2022.09.24 |
| 판다 기둥 세트 선정/제외 (0) | 2022.09.24 |
| xampp에서 mysql 버전을 업데이트하는 방법(innodb_additional_mem_pool_size 오류) (0) | 2022.09.23 |