特定のコード行にジャンプできるようにする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.
確かに、これはgotoに代わる最良の方法ではありません。しかし、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はあなたにとって言語ではない、と私は主張します。 :-)
私は最近 関数デコレータを書いた 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でPythonで実際に可能であり、デバッガAPIを誤用するだけでなく 他の人 のように実際に可能であることを指摘したいと思います。ただし、バイトコードをいじる必要があります。
これは official 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で言及されていること、そしてNiceソリューションのサンプルが提供されていることは非常に素晴らしいことです。 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
ブロックのインデントは正しいです。このコードは、ループPython構文の後にあいまいなelse
を使用します。 なぜpython forおよびwhileループの後に 'else'を使用するのですか?
作業バージョンが作成されました: 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"
言うまでもなく。はい、面白いですが、DONTはそれを使用します。
「goto」のようなステートメントをpythonに追加することは技術的に実行可能です。 pythonバイトコードのスキャンと変更に非常に役立つ「dis」モジュールと「new」モジュールを使用します。
実装の背後にある主なアイデアは、最初に「goto」および「label」ステートメントを使用するコードブロックをマークすることです。特別な「@goto」デコレータは、「goto」機能をマークする目的で使用されます。その後、これらの2つのステートメントについてそのコードをスキャンし、基礎となるバイトコードに必要な変更を適用します。これはすべて、ソースコードのコンパイル時に発生します。
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 __== '__main__':
@goto
def test1():
print 'Hello'
goto .the_end
print 'world'
label .the_end
print 'the end'
test1()
これが質問に答えることを願っています。
私は似たようなものを探していました
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ループから抜け出すのを助けるためにブール値を使うことでした:
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
これはあなたが探しているものに役立つと思います。
ユーザー定義の例外 を使用して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()
独自の方法でgotoを実行しています。別の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バージョンでのみ機能します)
同じ答えが欲しかったので、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)
フォワードGotoの場合は、次を追加できます。
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
ただし、これは単純なシナリオにのみ役立ちます(つまり、これらをネストすると混乱に陥ります)
pip3 install goto-statement
Python 2.6〜3.6およびPyPyでテスト済み。
リンク: goto-statement
foo.py
from goto import with_goto
@with_goto
def bar(start, stop):
label .bar_begin
...
goto .bar_begin
python gotoの代わりに、コードの簡単なテストのために次のようにbreakステートメントを使用します。これは、構造化コードベースがあることを前提としています。テスト変数は関数の開始時に初期化され、「If test:break」ブロックをテストするネストされたif-thenブロックまたはループの最後に移動し、コードの最後で戻り変数を変更します私がテストしているブロックまたはループ変数を反映します。
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()