2010-06-15 3 views
1

J'ai une méthode qui retournera un objet ou None si la recherche échoue. Quel style de ce qui suit est le meilleur?Quel style de retour est "meilleur" pour une méthode qui peut renvoyer None?

def get_foo(needle): 
    haystack = object_dict() 
    if needle not in haystack: return None 
    return haystack[needle] 

ou,

def get_foo(needle): 
    haystack = object_dict() 
    try: 
     return haystack[needle] 
    except KeyError: 
     # Needle not found 
     return None 

Je suis indécis quant à ce qui est plus plus souhaitable moi-même. Un autre choix serait return haystack[needle] if needle in haystack else None, mais je ne suis pas sûr que ce soit mieux.

+0

Est-ce que cela a vraiment été marqué comme wiki communautaire? – detly

+0

Je pensais que c'était la bonne façon de faire les choses pour les messages "subjectifs". Est-ce faux? – Daenyth

+0

Bonne question. Je ne suis pas sûr où la ligne est moi-même :) – detly

Répondre

10

Pour cet exemple, il ressemble à la méthode dictget est la plus concise:

def get_foo(needle): 
    haystack = object_dict() 
    return haystack.get(needle) 

En général, en Python, les gens ont tendance à préférer essayer/sauf que de vérifier quelque chose d'abord - voir l'entrée EAFP dans le glossary. Notez que de nombreuses fonctions "test for membership" utilisent des exceptions dans les coulisses.

Je ne vais pas commencer une flamewar sur les mérites relatifs des multiples déclarations ou les alternatives :)

+0

L'entrée EAFP vous avez mentionné est ce qui a suscité la question, surtout. Merci pour l'info sur dict.get(), je n'étais pas au courant qu'il a si bien géré cette situation. – Daenyth

+1

C'est une tâche courante - voir aussi [objets defaultdict] (http://docs.python.org/library/collections.html#defaultdict-objects). Quant à EAFP - tout le monde ne le suit pas, mais il vaut la peine de savoir quelles sont les conventions communes. Je suis coupable de l'ignorer moi-même quand je pense que c'est approprié. – detly

2

si les deux font exactement la même chose, choisir celui que vous aimez le plus et c'est plus facile à lire - j'aime la deuxième, mais les deux sont bons.

(peut-être un si cela est plus rapide que l'autre - donc si preformance est importante realy, tester et choisir le plus véloce)

+1

Comment diable peux-tu dire 'les deux sont bons'? Le premier effectue une recherche deux fois à chaque fois qu'il est appelé: une fois pour savoir si la clé est là, puis à nouveau pour obtenir et retourner la valeur. Cela me semble tout simplement stupide. –

+0

@Don: C'est un bon point que je n'avais même pas vraiment considéré. – Daenyth

-2

Dans toutes les langues que j'ai utilisé la première version est perferable. Les exceptions sont essentiellement des goto déguisés avec plusieurs des mêmes problèmes, donc je ne les utilise pas si je peux l'éviter.

Il existe également un coût de performance possible. Je ne connais pas Python, mais dans beaucoup d'autres langues, il y a un coût important pour créer l'exception que vous allez jeter sur la ligne suivante.

+3

Chaque structure de contrôle est un «goto» déguisé. Comparer des structures de contrôle sophistiquées et bien définies à 'goto 'n'a aucun sens. En outre, de nombreuses fonctions de "test d'appartenance" utilisent des exceptions en coulisses. – detly

+0

En ce qui concerne l'aspect vitesse, je n'ai pas profilé pour voir lequel est le plus rapide, mais mon intuition me dit que la version try/except peut être plus rapide dans le cas courant (aiguille trouvée). La première version testera l'expression if sur chaque appel, alors que l'essai/excepté n'utilisera que l'exception dans le cas d'échec. S'il vous plaît faites-moi savoir si j'ai un malentendu sur les internes vs ce que je viens de décrire cependant. En tout cas, ce ne sera pas un appel commun, donc c'est plus pour le style/lisibilité que la vitesse. – Daenyth

+0

@detly La plupart des structures de contrôle n'ont pas le comportement "sauter de n'importe où" que les exceptions ont. Vos points de sortie sont bien définis dans if-blocks et for-loops. C'est seulement dans les blocs try que chaque ligne devient effectivement un goto. –

Questions connexes