Pythonにlabel/gotoはありますか?

Pythonで特定のコード行にジャンプできるgotoやそれに相当するものはありますか?

質問へのコメント (4)

いいえ、Pythonはラベルやgotoをサポートしていません。Pythonは(高度に)構造化されたプログラミング言語です。

解説 (3)

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]1を参照のこと:

関数で囲むか、例外を使うのが一番です。 関数の場合

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 はあなたのための言語ではないと主張します。)

解説 (2)

私は最近、Pythonで「goto」を可能にする関数デコレーター1を書きました。

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

なぜそのようなことをしたいのか、私にはわかりません。 とはいえ、私はそれほど深刻ではありません。 しかし、この種のメタプログラミングは、Python、少なくともCPythonとPyPyで実際に可能であり、デバッガーAPIを他の男のように誤用するだけではないことを指摘しておきます。 ただし、バイトコードをいじる必要があります。

解説 (2)

これは公式python Design and History FAQで見つかりました。

なぜgotoがないのですか? 。 例外を使用して、機能する「構造化されたgoto」を提供できます。 関数呼び出し全体。 多くの人が、例外は都合の良いと感じている。 Cの「go」または「goto」コンストラクトのすべての合理的な使用をエミュレートします。 フォートラン、およびその他の言語。 例:

class label(Exception): pass  # declare a label

try:
    ...
    if condition: raise label()  # goto label
    ...
except label:  # where to goto
    pass
... 

これにより、ループの真ん中にジャンプすることはできませんが、それは可能です。 とにかく通常、ゴトの乱用と見なされます。 控えめに使用してください。

これが公式のFAQでも言及されており、優れたソリューションサンプルが提供されていることは非常に素晴らしいことです。 コミュニティはこのように「ゴト」さえ扱っているので、私は本当にpythonが好きです;)。

解説 (0)

bobince'さんのコメントからの提案を使って、@ascobol`'さんの質問に答えます1

for i in range(5000):
    for j in range(3000):
        if should_terminate_the_loop:
           break
    else: 
        continue # no break encountered
    break

elseブロックのインデントは正しいです。このコードはループの後に不明瞭なelse` を使っています。Python はなぜ for ループや while ループの後に 'else' を使うのか](https://stackoverflow.com/q/9979970/4279) を参照してください。

解説 (7)

作業バージョンが作成されました: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"

言うまでもない。 はい、面白いですが、使用しないでください。

解説 (2)

「ブレイク」と「コンティニュー」のラベルは、2007年のPEP 3136で提案されましたが、拒否されました。 提案の動機セクションは、Pythonで「ブレイク」というラベルを付けたものを模倣するためのいくつかの一般的な(エレガントでない場合)方法を示しています。

解説 (0)

一部の作業で「goto」のようなステートメントをpythonに追加することは技術的に実現可能です。 「dis」モジュールと「new」モジュールを使用します。どちらも、pythonバイトコードのスキャンと変更に非常に役立ちます。

実装の背後にある主なアイデアは、最初にコードのブロックに「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 __name__ == '__main__':

    @goto
    def test1():
        print 'Hello' 

        goto .the_end
        print 'world'

        label .the_end
        print 'the end'

    test1()

これが質問に答えることを願っています。

解説 (0)

[ユーザー定義の例外][1]を使用して「goto」をエミュレートできます。

例:


class goto1(Exception):
    pass   
class goto2(Exception):
    pass   
class goto3(Exception):
    pass   

def loop():
    print 'start'
    num = input()
    try:
        if num
解説 (2)

似たものを探していました。

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
解説 (0)

今あります。 ゴト

これはあなたが探しているものに役立つかもしれないと思います。

解説 (0)

同じ答えが欲しかったし、「ゴト」を使いたくなかった。 そこで、次の例を使用しました(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)
解説 (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バージョンでのみ機能します)。

解説 (0)

前進ゴトの場合は、以下を追加できます。

while True:
  if some condition:
    break
  #... extra code
  break # force code to exit. Needed at end of while loop
#... continues here

ただし、これは単純なシナリオ(つまり、. これらをネストすると、混乱に陥ります)。

解説 (0)

python goto相当の代わりに、コードのクイックテストに次の方法でbreakステートメントを使用します。 これは、構造化されたコードベースを持っていることを前提としています。 テスト変数は関数の開始時に初期化され、&quotを移動します。;テストの場合:break&quot。; テストしたいネストされたif-thenブロックまたはループの最後までブロックします。, コードの最後にある戻り変数を変更して、ブロックまたはループ変数I&#39を反映させます。;mテスト。

def x:
  test = True
  If y:
     # some code
     If test:
            break
  return something
解説 (0)

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()  
解説 (0)

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(start, stop):

    label .bar_begin

    ...

    goto .bar_begin
解説 (0)