2010-08-16 23 views
5

Je suis sûr que ce concept a déjà été proposé, mais je ne trouve pas de réponse simple et satisfaisante. L'utilisation d'try/finally est-elle un mauvais moyen de gérer des fonctions avec plusieurs retours? Par exemple, j'aipython essayer/enfin pour le contrôle de flux

 

try: 
    if x: 
     return update(1) 
    else: 
     return update(2) 
finally: 
    notifyUpdated() 
 

Ce tout semble plus agréable que le stockage des commandes mise à jour() dans une variable temporaire et retour qui.

Répondre

11

Je ne le recommanderais pas. D'abord parce que notifyUpdated() sera appelé même si le code de l'une ou l'autre branche lève une exception. Vous auriez besoin quelque chose comme ça pour vraiment le comportement prévu:

try: 
    if x: 
     return update(1) 
    else: 
     return update(2) 
except: 
    raise 
else: 
    notifyUpdated() 

En second lieu, parce que try blocs indiquent que vous êtes généralement faire une sorte de gestion des exceptions, et vous n'êtes pas, vous êtes juste de les utiliser pour commodité. Donc, cette construction va dérouter les gens. Par exemple, je ne pense pas que l'une ou l'autre des deux premières personnes (dont au moins une a supprimé sa réponse) pour répondre à votre question ait réalisé ce que vous essayiez réellement de faire. Code déroutant est mauvais, peu importe comment pratique et intelligent il semble.

+0

Bon point à ce sujet est tellement confus que les deux premières réponses ont raté la marque. –

0

de http://docs.python.org/library/contextlib.html:


from contextlib import closing 
import urllib 

with closing(urllib.urlopen('http://www.python.org')) as page: 
    for line in page: 
     print line 

vous pouvez donc créer une fonction similaire et l'utiliser

+0

ne répond pas vraiment à la question des postes d'observation. – Omnifarious

+0

'with' stmt est un moyen légitime d'assurer le nettoyage à proximité – amwinter

3

Je pense que vous voulez dire que vous voulez utiliser try/finally comme alternative à ceci:

if x: 
    result = update(1) 
else: 
    result = update(2) 
notifyUpdated() 
return result 

Je suppose que cela est une question de style. Pour moi j'aime réserver try pour la manipulation exceptionnelle conditionnelle. Je ne l'utiliserai pas comme une déclaration de contrôle de flux.

+0

Bien que je suppose que c'est une question de style, je ne pense pas que cela signifie que la question n'a pas de réponse par oui ou par non. Je dirais définitivement «non» pour la raison que vous avez indiquée et parce que c'est plus déroutant. – Omnifarious

+0

Je suis d'accord. Je devrais prendre une position plus forte. –

11

Je n'utiliserais pas try/finally pour un flux qui n'implique pas d'exceptions. C'est trop compliqué pour son propre bien.

C'est mieux:

if x: 
    ret = update(1) 
else: 
    ret = update(2) 
notifyUpdated() 
return ret 
3

Je pense que cela demande des ennuis. Que se passe-t-il plus tard, lorsque vous changez votre code à ce qui suit?

try: 
    if x: 
     return update(1) 
    elif y: 
     return update(2) 
    else: 
     return noUpdateHere() 
finally: 
    notifyUpdated() # even if noUpdateHere()! 

Au mieux, il est un point achoppement pour la plupart des lecteurs de votre code (probablement même vous en six mois), parce qu'il utilise try/finally dans un but qui diffère des modèles d'utilisation normale. Et le typage qu'il enregistre est minime, de toute façon.

+0

J'ai raté ce point d'achoppement. Ce cas existe déjà sous forme masquée dans l'original mais parce que si 'update (1)' ou 'update (2)' renvoie une exception qui signifie aussi probablement 'notifyUpdated()' ne devrait pas être appelée. – Omnifarious

3

Je pense qu'un décorateur est une meilleure idée ici

def notifyupdateddecorator(f): 
    def inner(*args, **kw): 
     retval = f(*args, **kw) 
     notifyUpdated() 
     return retval 
    return inner 

@notifyupdateddecorator 
def f(x): 
    if x: 
     return update(1) 
    else: 
     return update(2) 

@notifyupdateddecorator 
def g(x): 
    return update(1 if x else 2) 
+0

Hmm, je n'ai jamais vu ça à propos de décorateurs personnalisés. Avez-vous un lien vers où cela est décrit? – Falmarri

+0

@Falmarri, http://docs.python.org/glossary.html#term-decorator –