goto
Python'da belirli bir kod satırına atlayabilmek için bir ya da eşdeğeri var mı ?
goto
Python'a Fortran kodunu Python'a çevirirken uygulandı. Bunun için kendinden nefret ediyordu.
goto
Python'da belirli bir kod satırına atlayabilmek için bir ya da eşdeğeri var mı ?
goto
Python'a Fortran kodunu Python'a çevirirken uygulandı. Bunun için kendinden nefret ediyordu.
Yanıtlar:
Python, birinci sınıf işlevleri kullanarak bir goto ile yapabileceğiniz bazı şeyleri yapma olanağı sunar. Örneğin:
void somefunc(int a)
{
if (a == 1)
goto label1;
if (a == 2)
goto label2;
label1:
...
label2:
...
}
Python'da şu şekilde yapılabilir:
def func1():
...
def func2():
...
funcmap = {1 : func1, 2 : func2}
def somefunc(a):
funcmap[a]() #Ugly! But it works.
Kabul ettim, bu goto'nun yerine geçmenin en iyi yolu değil. Ancak, goto ile ne yapmaya çalıştığınızı tam olarak bilmeden, özel tavsiyeler vermek zor.
@ ascobol :
En iyi seçeneğiniz, onu bir işleve dahil etmek veya bir istisna kullanmaktır. İşlev için:
def loopfunc():
while 1:
while 1:
if condition:
return
İstisna için:
try:
while 1:
while 1:
raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
pass
Bunun gibi şeyler yapmak için istisnalar kullanmak, başka bir programlama dilinden gelirseniz biraz garip gelebilir. Ancak, istisnaları kullanmaktan hoşlanmıyorsanız, Python'un sizin için bir dil olmadığını iddia ediyorum. :-)
loopfunc
genellikle girdiler ve uygulanması için biraz daha çaba gerektirecektir, ancak çoğu durumda bence en iyi yol budur.
Son zamanlarda Python'da da böyle bir fonksiyon dekoratörü yazdımgoto
, tıpkı şöyle:
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
Neden böyle bir şey yapmak istediğinden emin değilim. Bununla ilgili çok ciddi değilim dedi. Ancak, bu tür bir meta programlamanın Python'da, en azından CPython ve PyPy'de mümkün olduğunu ve sadece diğer adamın yaptığı gibi hata ayıklayıcı API'sini yanlış kullanarak değil de mümkün olduğunu belirtmek isterim . Yine de bayt kodu ile uğraşmak zorunda.
.begin
ve .end
etiketler?
Bunu resmi python Tasarım ve Tarih SSS bölümünde buldum .
Neden gitmiyor?
İşlev çağrılarında bile çalışan “yapılandırılmış bir goto” sağlamak için istisnaları kullanabilirsiniz. Birçok kişi, istisnaların C, Fortran ve diğer dillerin “git” veya “git” yapılarının tüm makul kullanımlarını uygun bir şekilde taklit edebileceğini düşünmektedir. Örneğin:
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
Bu, bir döngünün ortasına atlamanıza izin vermez, ancak genellikle yine de bir goto kötüye kullanımı olarak kabul edilir. Dikkatli kullanın.
Bunun resmi SSS'de bile belirtilmesi ve hoş bir çözüm örneğinin sağlanması çok güzel. Python'u gerçekten seviyorum çünkü topluluğu bile goto
böyle davranıyor;)
goto
, emin olmak için büyük bir programlama foux pas, ancak taklit etmek goto
için IMO kötüye kullanım istisnaları sadece biraz daha iyidir ve yine de çok fazla kaşlarını çatmak gerekir. Ben aslında Python yaratıcıları goto
izin vermemek için aslında yararlı olduğu birkaç kez dilde dahil olurdu çünkü "kötü, çocuklar" ve daha sonra aynı işlevselliği (ve aynı kod spagettifikasyon) almak için istisna istismar öneririz.
@ascobol
'Sorusunu@bobince
yorumlardan gelen öneriyi kullanarak cevaplamak için :
for i in range(5000):
for j in range(3000):
if should_terminate_the_loop:
break
else:
continue # no break encountered
break
else
Bloğun girintisi doğrudur. Kod else
bir döngü Python sözdiziminden sonra belirsiz kullanır . Bkz Neden ve while döngüleri sonra piton kullanımı 'başka' nedir?
else
yürütüldüğünde döngü sonrasında ise break
karşılaşılan edilmemiştir. Etkisi, hem iç hem de dış halkaları should_terminate_the_loop
sonlandırmasıdır .
return
@Jason Baker tarafından önerilen , derin yuvalanmış döngülerden kurtulmak için iyi bir alternatiftir.
Çalışan bir sürüm hazırlandı: http://entrian.com/goto/ .
Not: April Fool'un şakası olarak sunuldu. (yine de çalışıyor)
# 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"
Söylemeye gerek yok. Evet komik, ama DONT kullanmayın.
İçin etiketler break
ve continue
önerilmiştir PEP 3136 2007 yılında arka ancak reddedildi. Motivasyon teklifin bölüm birkaç yaygın (inelegant ise) etiketli taklit için yöntemler göstermektedir break
Python.
Bazı çalışmalarla python'a 'git' benzeri bir ifade eklemek teknik olarak mümkündür. Her ikisi de python bayt kodunu taramak ve değiştirmek için çok yararlı olan "dis" ve "new" modüllerini kullanacağız.
Uygulamanın arkasındaki ana fikir ilk olarak bir kod bloğunu "git" ve "etiket" ifadelerini kullanarak işaretlemektir. "Git" işlevlerini işaretlemek için özel bir "@goto" dekoratörü kullanılacaktır. Daha sonra bu kodu bu iki ifade için tarar ve temel bayt koduna gerekli değişiklikleri uygularız. Tüm bunlar kaynak kodu derleme zamanında gerçekleşir.
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()
Umarım bu soruya cevap verir.
taklit etmek için Kullanıcı Tanımlı İstisnalar kullanabilirsinizgoto
misal:
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()
pip3 install goto-statement
Python 2.6 - 3.6 ve PyPy üzerinde test edilmiştir.
Link: goto-bildirimi
foo.py
from goto import with_goto
@with_goto
def bar():
label .bar_begin
...
goto .bar_begin
Benzer bir şey arıyordum
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;
Bu yüzden yaklaşımım, iç içe döngülerden kurtulmak için bir boole kullanmaktı:
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
Aynı cevabı istedim ve kullanmak istemedim goto
. Bu yüzden aşağıdaki örneği kullandım (learnpythonthehardway'den)
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)
Gotos yapmak için kendi yolum var. Ayrı python komut dosyaları kullanıyorum.
Eğer döngü istiyorum:
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")
( NOT: Bu teknik yalnızca Python 2.x sürümlerinde çalışır)
Bir python goto eşdeğeri yerine kodumu hızlı testler için aşağıdaki şekilde break ifadesini kullanın. Bu, yapılandırılmış kod tabanınız olduğunu varsayar. Test değişkeni fonksiyonunuzun başlangıcında başlatılır ve sadece "If test: break" bloğunu test etmek istediğim iç içe if-then bloğunun veya döngüsünün sonuna taşıyorum, kodun sonunda dönüş değişkenini değiştiriyorum Ben test blok veya döngü değişkeni yansıtmak için.
def x:
test = True
If y:
# some code
If test:
break
return something
goto/label
Python'da eşdeğer bir kod olmasa da, goto/label
döngüler kullanma gibi bir işlevsellik elde edebilirsiniz .
Aşağıda, goto/label
python dışında rastgele bir dilde kullanılabilecek bir kod örneği alalım .
String str1 = 'BACK'
label1:
print('Hello, this program contains goto code\n')
print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
str1 = input()
if str1 == 'BACK'
{
GoTo label1
}
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')
Şimdi yukarıdaki kod örneğinin aynı işlevselliği, while
aşağıda gösterildiği gibi bir döngü kullanılarak python'da elde edilebilir .
str1 = 'BACK'
while str1 == 'BACK':
print('Hello, this is a python program containing python equivalent code for goto code\n')
print('Now type BACK if you want the program to go back to the above line of code. Or press the ENTER key if you want the program to continue with further lines of code')
str1 = input()
print('Program will continue\nBla bla bla...\nBla bla bla...\nBla bla bla...')
hayır, goto ifadesini uygulamanın alternatif bir yolu var
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()