파이썬에 특정 코드 줄로 이동할 수 있는 goto
또는 이와 동등한 기능이 있나요?
파이썬은 일급 함수를 사용하여 고토로 할 수 있는 몇 가지 작업을 수행할 수 있는 기능을 제공합니다. 예를 들어
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
파이썬에서는 다음과 같이 할 수 있습니다:
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
다른 프로그래밍 언어에서 왔다면 예외를 사용하여 이와 같은 작업을 수행하는 것이 약간 어색하게 느껴질 수 있습니다. 하지만 예외를 사용하는 것이 싫다면 파이썬은 여러분을 위한 언어가 아니라고 주장하고 싶습니다.)
필자는 최근 작성했습니까 함수 데코레이터 할 수 있는 '이동' 의 파이썬, 그냥 그렇게:
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
내가 찾은 이 중 [공식 파이썬 설계 및 기록 FAQ] [1].
>. 고토 없는 이유는? >. >. 이런 예외 "구조적 이동" 작동됨 제공하기 위해 사용할 수 있습니다. >. 함수 호출을 통해. 수 많은 예외 있음을 느낄 수 있습니다. >. 모든 합당한 에뮬레이트합니다 사용된 "go" 또는 "이동" 컨스트럭트 C, >. 포트란, 기타 언어. 예를 들면 다음과 같습니다.
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
>. 이 싫어하겠어 수 있지만 그건 가운데로 루프 점프 >. 일반적으로 남용을 옵션이므로 이동 겁니다. 사용 자제.
[1]: https://docs.python.org/3/faq/design.html # 왜 없는 이동
댓글에서 @bobince
의 제안을 사용하여 @ascobol
의 질문에 답변합니다:
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
else블록의 들여쓰기가 올바릅니다. 이 코드는 루프 파이썬 구문 뒤에 모호한
else`를 사용합니다. 파이썬에서 for 및 while 루프 뒤에 'else'를 사용하는 이유는 무엇인가요?](https://stackoverflow.com/q/9979970/4279)를 참조하세요.
작업 버전에 작성되었습니다. http://entrian.com/goto/.
참고: # 39 의 표시됨과 제공하는 것은 4월 Fool& 농담으로 받아들였다. (apc® 표시되어도)
# 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"
말할 나위 없이. 그 재미 있지만, 이를 사용하여 그러하너라 않습니다.
레이블 '브레이크' 와 '에서 PEP 3136 지난 2007년 제안된 계속하시겠습니까' 등이 있지만, 이것은 거부되었다. [동기부여] [2] 이 제안을 몇 가지 공통적인 부분은 '브레이크' 의 파이썬 (우아하지 않은 경우) 방법을 보여줍니다 레이블된 비난한다.
[2]: http://www.python.org/dev/peps/pep-3136/ # 동기 부여
이 방식은 뒤에 주된 아이디어는 먼저 lesher 코드 블록을 사용하는 것과 " goto"; 및 " label"; 명령문입니다. 특별한 " @goto"; 데코레이터 사용할 목적으로 표시 " goto"; 총괄하였습니다. 이후 두 가지 수정이 필요한 경우 기본 진술, 우리는 그 코드를 스캑 적용하십시오 바이트 코드. 이 모든 일이 발생합니까 dell. 소스 코드를 컴파일 타임.
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()
이 질문에 대한 답변 바랍니다.
[사용자정의된 예외] [1] 에뮬레이션하도록 '이동' 사용할 수 있습니다.
예:
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()
[1]: https://docs.python.org/2/tutorial/errors.html # 사용자 정의 예외
내가 찾던 일부 유사한 것
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;
그래서 제 사용할 수 있도록 끊기 위해 밖으로 외곽진입 sanlight 부울입니다 네스트된 루프:
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
이제. 이동
내 생각엔 이 찾고 뭐하러요 도움이 될 것입니다.
그리고 난 내가 원하는 답을 똑같이 사용할 일부러 '이동'. 그래서 내가 사용한 다음 예 (레안피토나하드웨이 에서)
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)
나는 내 방식대로 하고 이동. 내가 사용하는 별도의 파이썬 스크립트입니다.
If I want to 루프:
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")
( NOTE: 때만 이 기법을 의 파이썬 2.x 버전)
앞으로 이동, 추가하기만 사용할 수 있습니다.
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
이 문제는 단순한 시나리오용으로 emailxtender 표시되어도 (즉, 이러한 아니하였으매 엉망하지 붙여넣습니다 중첩할 있습니다)
내가 사용하는 대신 avamer 브레이크 (break) 는 다음과 같은 방법으로 테스트를 위한 파이썬 goto 문을 신속시작 내 코드. 여기에서는 기본 구조화된 코드로 있습니다. 테스트 가변입니다 초기화되었습니다 시작할 때, 난 그냥 사용하는 함수가 움직이십시오 ", 만약 테스트: break". 끝까지 블록이어야 네스트된 경우-다음 블록 또는 고리 I, 수정 끝에 가변적입니다 테스트하려면 복귀하십시오 코드 블록 또는 반영하여, 루프 변수를 I& # 39 m 테스트.
def x:
test = True
If y:
# some code
If test:
break
return something
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
>. 파이썬 2.6 통해 거친 3.6tb 및 PyPy.
링크: goto 문
foo.py
from goto import with_goto
@with_goto
def bar(start, stop):
label .bar_begin
...
goto .bar_begin