Есть ли goto
или любой эквивалент в Python, чтобы иметь возможность перейти к определенной строке кода?
Есть ли метка /goto в Python?
Ответ 1
Нет, Python не поддерживает метки и goto, если это то, что вам нужно. Это (высоко) структурированный язык программирования.
Ответ 2
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, трудно дать конкретные советы.
@аскобол:
Лучше всего либо заключить его в функцию, либо использовать исключение. Для функции:
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 не является для вас языком.: -)
Ответ 3
Недавно я написал декоратор функций, который позволяет goto
в Python, точно так же:
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 отладчика в качестве другого парня сделал. Вы должны возиться с байт-кодом, хотя.
Ответ 4
Я нашел это в официальном FAQ по настройке и истории python.
Почему нет goto?
Вы можете использовать исключения, чтобы обеспечить "структурированную перестановку", которая даже работает через вызовы функций. Многие считают, что исключения могут подражать всем разумным применениям конструкций "go" или "goto" C, Фортране и других языках. Например:
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
Это не позволяет вам прыгать в середину цикла, но thats обычно считается злоупотреблением goto. Используйте экономно.
Очень приятно, что это даже упоминается в официальном FAQ, и что предоставляется хороший образец решения. Мне очень нравится python, потому что его сообщество обрабатывает даже goto
как это;)
Ответ 5
Чтобы ответить на вопрос @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
правильный. Код использует неясное else
после циклы синтаксиса Python. См. Почему Python использует "else" после циклов for и while?
Ответ 6
Сделана рабочая версия: 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 его использовать.
Ответ 7
Ярлыки для break
и continue
были предложены в Motivation иллюстрирует несколько общих (если неэлегантных) методов имитации помеченных break
в Python.
Ответ 8
Технически возможно добавить инструкцию 'goto' на python с некоторой работой. Мы будем использовать модули "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()
Надеюсь, что это ответит на вопрос.
Ответ 9
вы можете использовать Пользовательские исключения для эмуляции 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()
Ответ 10
Я искал нечто похожее на
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
Ответ 11
Сейчас. goto
Я думаю, что это может быть полезно для того, что вы ищете.
Ответ 12
Мне нужен тот же ответ, и я не хотел использовать goto
. Поэтому я использовал следующий пример (из учебного плана)
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)
Ответ 13
У меня есть свой способ делать gotos. Я использую отдельные скрипты 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)
Ответ 14
Для форвард Гото, вы можете просто добавить:
while True:
if some condition:
break
#... extra code
break # force code to exit. Needed at end of while loop
#... continues here
Это помогает только для простых сценариев (то есть, их вложение приведет вас в беспорядок)
Ответ 15
Вместо эквивалента Python Goto я использую оператор break следующим образом для быстрых тестов моего кода. Это предполагает, что у вас есть структурированная кодовая база. Тестовая переменная инициализируется в начале вашей функции, и я просто перемещаю блок "If test: break" в конец вложенного блока if-then или цикла, который я хочу проверить, изменяя возвращаемую переменную в конце кода чтобы отразить блочную или циклическую переменную, которую я тестирую.
def x:
test = True
If y:
# some code
If test:
break
return something
Ответ 16
нет, есть альтернативный способ реализации оператора 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()
Ответ 17
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
Ответ 18
В Python оператор goto поддерживается с помощью goto.<label_name>
и label.<label_name>
. Для получения дополнительной информации перейдите по этой ссылке.
def func():
resp = call_something()
if resp != 0: # Failure case
goto .failure_handler
....
....
resp = ....
if resp != 0: # Failure case
goto .failure_handler
....
....
label .failure_handler
cleanup
return -1
Обычно на всей планете люди рекомендуют избегать использования оператора goto. Но обработка ошибок в функции может быть хорошо обработана только с помощью оператора goto. Даже я не предпочитаю использовать goto, кроме обработчика сбоев.