265 votes

Existe-t-il un label/goto en Python ?

Y a-t-il un goto ou tout autre équivalent en Python pour pouvoir sauter à une ligne de code spécifique ?

3 votes

L'étiquette est assez vague. Pouvez-vous être plus précis sur ce que vous recherchez ?

16 votes

25 votes

Un de mes amis a mis en place goto en Python alors qu'il traduisait du code Fortran en Python. Il s'est détesté pour ça.

168voto

unwind Points 181987

Non, Python ne supporte pas les labels et les goto, si c'est ce que vous recherchez. Il s'agit d'un langage de programmation (hautement) structuré.

111voto

Jason Baker Points 56682

Python vous offre la possibilité de faire certaines des choses que vous pourriez faire avec un goto en utilisant des fonctions de première classe. Par exemple :

void somefunc(int a)
{
    if (a == 1)
        goto label1;
    if (a == 2)
        goto label2;

    label1:
        ...
    label2:
        ...
}

Cela pourrait être fait en python comme ceci :

def func1():
    ...

def func2():
    ...

funcmap = {1 : func1, 2 : func2}

def somefunc(a):
    funcmap[a]()  #Ugly!  But it works.

D'accord, ce n'est pas la meilleure façon de remplacer goto. Mais sans savoir exactement ce que vous essayez de faire avec le goto, il est difficile de donner des conseils spécifiques.

@ ascobol :

Votre meilleure chance est de l'enfermer dans une fonction ou d'utiliser une exception. Pour la fonction :

def loopfunc():
    while 1:
        while 1:
            if condition:
                return

Pour l'exception :

try:
    while 1:
        while 1:
            raise BreakoutException #Not a real exception, invent your own
except BreakoutException:
    pass

L'utilisation d'exceptions pour faire ce genre de choses peut sembler un peu étrange si vous venez d'un autre langage de programmation. Mais je dirais que si vous n'aimez pas utiliser les exceptions, Python n'est pas le langage qu'il vous faut :-)

0 votes

Utilisez-le judicieusement. Les exceptions en Python sont plus rapides que dans la plupart des autres langages. Mais elles restent lentes si vous les utilisez à tort et à travers.

0 votes

Juste un avis : loopfunc nécessitera généralement des entrées et un peu plus d'efforts à mettre en œuvre, mais c'est la meilleure solution dans la plupart des cas, je pense.

5 votes

Désolé, mais les exceptions ne devraient pas être utilisées pour contrôler le flux du programme de cette façon.

105voto

Sebastian Noack Points 458

J'ai récemment a écrit un décorateur de fonction qui permet goto en Python, juste comme ça :

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

Je ne suis pas sûr de savoir pourquoi on voudrait faire quelque chose comme ça. Cela dit, je ne suis pas trop sérieux à ce sujet. Mais j'aimerais souligner que ce genre de méta-programmation est réellement possible en Python, au moins dans CPython et PyPy, et pas seulement en abusant de l'API de débogage comme cela L'autre gars a fait. Vous devez cependant manipuler le bytecode.

4 votes

Super décorateur que vous avez fait ! C'est génial de pouvoir manipuler le bytecode :-)

0 votes

Je pense que cela devrait être la réponse acceptée pour cette question. Cela pourrait être utile pour de nombreuses boucles imbriquées, pourquoi pas ?

0 votes

Est-ce que cela ne prend en charge que .begin et .end des étiquettes ?

53voto

klaas Points 689

J'ai trouvé ceci dans le FAQ officielle sur la conception et l'histoire de python .

Pourquoi n'y a-t-il pas de goto ?

Vous pouvez utiliser les exceptions pour fournir un "goto structuré" qui fonctionne même à travers les appels de fonction. Beaucoup pensent que les exceptions peuvent commodément émuler toutes les utilisations raisonnables des constructions "go" ou "goto" du C, Fortran, et d'autres langages. Par exemple :

class label(Exception): pass  # declare a label

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

Cela ne permet pas de sauter au milieu d'une boucle, mais c'est de toute façon généralement considéré comme un abus de goto. Utilisez-le avec parcimonie.

C'est une bonne chose que cela soit mentionné dans la FAQ officielle et qu'un exemple de solution soit fourni. J'aime vraiment python parce que sa communauté traite même les problèmes les plus graves. goto comme ceci ;)

5 votes

Abuser de goto est un foux pas majeur de la programmation pour être sûr, mais OMI abusant des exceptions pour émuler goto n'est que légèrement meilleur et devrait toujours être fortement désapprouvé. J'aurais préféré que les créateurs de Python incluent goto dans le langage pour les rares occasions où cela est réellement utile plutôt que de l'interdire parce que "c'est mauvais, les gars" et de recommander ensuite d'abuser des exceptions pour obtenir la même fonctionnalité (et la même spaghettification du code).

1 votes

C'est une partie intéressante de la FAQ. Le titre de la FAQ est un peu trompeur car il ne répond pas vraiment à la partie "Pourquoi".

0 votes

@np8 : Je pense que c'est le cas en disant que .. "Vous pouvez utiliser les exceptions pour fournir un 'goto structuré' "... et que ... "Beaucoup pensent que les exceptions peuvent émuler de manière pratique toutes les utilisations raisonnables du 'go' ou 'goto'". J'interprète donc cela comme "il n'y a pas de goto dédié en python parce que la fonctionnalité et même un peu plus peut "facilement" être réalisée en utilisant d'autres mécanismes du langage. Mais je suis également d'accord sur le fait qu'il n'y a pas de véritable raison pour laquelle il n'a pas été ajouté comme un "sucre syntaxique". Encore une fois IMHO je pense que l'accent est mis sur le "structuré" par opposition à un goto qui pourrait littéralement sauter n'importe où dans le code.

21voto

harmv Points 354

Une version de travail a été réalisée : http://entrian.com/goto/ .

Note : Il a été proposé comme une blague de poisson d'avril. (qui fonctionne cependant)

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

Inutile de le dire. Oui, c'est drôle, mais ne l'utilisez pas.

5 votes

Cela me semble mieux que d'utiliser 3 pauses... bien sûr, il y a aussi d'autres façons de l'écrire.

1 votes

Nick L'utilisation d'une fonction avec retour est encore mieux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X