INTERESTING FACTS BLOG

Painting and Sketches

Goto для Python

Оригинальная статья: goto for Python

Автор статьи: Ричи Хиндл (Richie Hindle)

Источник: http://entrian.com/goto/

Модуль «Гото» была первоапрельская шутка, опубликованный 1 апреля 2004 г. Да, это работает, но это шутка, тем не менее. Пожалуйста, не используйте его в реальном коде!

 

Добавляет ключевые слова 'goto' и 'comefrom' для Python.

Ключевые слова 'goto' и 'comefrom' добавляют гибкость механизмам управления потоком Python и позволяют программистам Python использовать многие общие идиомы потока управления, которые ранее им отказывали. Ниже приведены некоторые примеры.

Чтобы включить новые ключевые слова, добавьте следующую строку в начало вашего кода:

from goto import goto, comefrom, label

goto

'goto' переводит выполнение программы непосредственно в другую строку кода. Целевая линия должна быть идентифицирована с помощью оператора 'label'. Этикетки определяются с использованием ключевого слова 'label' и имеют имена, которые являются произвольными идентификаторами Python с префиксом одной точки, например:

label .myLabel

Чтобы перейти к метке, используйте ключевое слово 'goto' следующим образом:

goto .myLabel

Вычисленный goto

Вы можете использовать вычисляемый goto, назначив имя метки переменной во время выполнения и ссылаясь на нее, используя следующую звездочку:

x = calculateLabelName()
goto *x

Значение «x» не должно содержать ведущую точку. См. Пример 5 ниже для полного примера.

comefrom

'comefrom' - это противоположность 'goto'. Это позволяет кусочку кода сказать «Когда бы ни была достигнута метка X, перейдите сюда». Например:

# ...code 1...
label .somewhere
# ...code 2...
comefrom .somewhere

Здесь «code 2» не будет выполняться - выполнение перейдет непосредственно из строки «label.somewhere» в строку «comefrom.somewhere». 'comefrom' обычно используется в качестве средства отладки - его использование в производственном коде не рекомендуется, поскольку оно может привести к неожиданному поведению.

Ограничения

Есть некоторые классы goto и comefrom, которые были бы неписаны, и, следовательно, есть некоторые ограничения на то, куда могут идти прыжки:

Примеры

Вот несколько примеров того, как можно использовать goto и comefrom:

# 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"


# Example 2: Restarting a loop:
from goto import goto, label
label .start
for i in range(1, 4):
    print i
    if i == 2:
        try:
            output = message
        except NameError:
            print "Oops - forgot to define 'message'!  Start again."
            message = "Hello world"
            goto .start
print output, "\n"


# Example 3: Cleaning up after something fails:
from goto import goto, label

# Imagine that these are real worker functions.
def setUp(): print "setUp"
def doFirstTask(): print 1; return True
def doSecondTask(): print 2; return True
def doThirdTask(): print 3; return False  # This one pretends to fail.
def doFourthTask(): print 4; return True
def cleanUp(): print "cleanUp"

# This prints "setUp, 1, 2, 3, cleanUp" - no "4" because doThirdTask fails.
def bigFunction1():
    setUp()
    if not doFirstTask():
        goto .cleanup
    if not doSecondTask():
        goto .cleanup
    if not doThirdTask():
        goto .cleanup
    if not doFourthTask():
        goto .cleanup

    label .cleanup
    cleanUp()

bigFunction1()
print "bigFunction1 done\n"


# Example 4: Using comefrom to let the cleanup code take control itself.
from goto import comefrom, label
def bigFunction2():
    setUp()
    if not doFirstTask():
        label .failed
    if not doSecondTask():
        label .failed
    if not doThirdTask():
        label .failed
    if not doFourthTask():
        label .failed

    comefrom .failed
    cleanUp()

bigFunction2()
print "bigFunction2 done\n"


# Example 5: Using a computed goto:
from goto import goto, label

label .getinput
i = raw_input("Enter either 'a', 'b' or 'c', or any other letter to quit: ")
if i in ('a', 'b', 'c'):
    goto *i
else:
    goto .quit

label .a
print "You typed 'a'"
goto .getinput

label .b
print "You typed 'b'"
goto .getinput

label .c
print "You typed 'c'"
goto .getinput

label .quit
print "Finished\n"


# Example 6: What happens when a label is missing:
from goto import goto, label
label .real
goto .unreal      # Raises a MissingLabelError exception.

 

Этот модуль выпущен под лицензией Python Software Foundation, который можно найти по адресу http://www.python.org/ Для этого требуется Python 2.3 или новее.

Ричи Хиндл, [email protected]

Версия 1.0, выпущенная 1 апреля 2004 года. Скачайте здесь.