41 votes

Existe-t-il un moyen plus pythonique de combiner une instruction Else: et une exception:?

J'ai un morceau de code qui effectue des recherches sur AutoCAD pour les zones de texte qui contiennent certains mots-clés (par exemple. "overall_weight" dans ce cas) et la remplace par une valeur à partir d'un dictionnaire. Parfois, cependant, la clé de dictionnaire est affecté à une chaîne vide et parfois, la clé n'existe pas tout à fait. Dans ces cas, l' "overall_weight" mots-clés doivent être remplacés par "N/A". Je me demandais si il y avait une plus pythonic moyen de combiner l' KeyError d'exception et l' else à la fois aller à l' nObject.TextString = "N/A" donc ce n'est pas tapé deux fois.

if nObject.TextString == "overall_weight":
    try:
        if self.var.jobDetails["Overall Weight"]:
            nObject.TextString = self.var.jobDetails["Overall Weight"]
        else:
            nObject.TextString = "N/A"
    except KeyError:
        nObject.TextString = "N/A"

Edit: Pour les précisions pour les futurs visiteurs, il y a seulement 3 cas, j'ai besoin de prendre soin de, et la réponse correcte prend soin de tous les 3 cas, sans rembourrage supplémentaire.

  1. dict[key] existe et points d'une chaîne non vide. TextString remplacé par la valeur attribuée à l' dict[key].

  2. dict[key] existe et pointe vers une chaîne vide. TextString remplacé par "N/A".

  3. dict[key] n'existe pas. TextString remplacé par "N/A".

67voto

user3155933 Points 43

Utilisez dict.get() qui renverra la valeur associée à la clé donnée si elle existe sinon None . (Notez que '' et None sont les deux valeurs de falsey.) Si s est vrai, affectez-le à nObject.TextString sinon donnez-lui une valeur de "N/A" .

 if nObject.TextString == "overall_weight":
    nObject.TextString = self.var.jobDetails.get("Overall Weight") or "N/A"
 

17voto

notorious.no Points 2883

Utilisez la fonction get() pour les dictionnaires. Il renverra None si la clé n'existe pas ou si vous spécifiez une deuxième valeur, elle le définira comme valeur par défaut. Ensuite, votre syntaxe ressemblera à:

 nObject.TextString = self.var.jobDetails.get('Overall Weight', 'N/A')
 

9voto

elethan Points 6867

Utilisez .get() avec un argument par défaut de "N/A" qui sera utilisé si la clé n'existe pas:

 nObject.TextString = self.var.jobDetails.get("Overall Weight", "N/A")
 

Mettre à jour

Si des chaînes vides doivent être traitées, modifiez simplement comme suit:

 nObject.TextString = self.var.jobDetails.get("Overall Weight") or "N/A"
 

Cela définira nObject.TextString sur "N / A" si un KeyError est généré ou si la valeur extraite est vide: '' , [] , etc.

3voto

tdelaney Points 7235

Je pense que c'est une bonne affaire pour le réglage de la valeur par défaut à l'avance

if nObject.TextString == "overall_weight":
    nObject.TextString = "N/A"
    try:
        if self.var.jobDetails["Overall Weight"]:
            nObject.TextString = self.var.jobDetails["Overall Weight"]
    except KeyError:
        pass

REPENSER

Le fossé qui première réponse (juste le garder car il a obtenu un upvote). Si vous voulez vraiment aller pythonic, (et que vous voulez toujours de définir une valeur sur TextString) remplacer l'ensemble de la chose avec

nObject.TextString = (nObject.TextString == "overall_weight"
    and self.var.jobDetails.get("Overall Weight")
    or "N/A")

Python and et or des opérations de retour de leur dernière valeur calculée, pas Vrai/Faux et vous pouvez l'utiliser pour marcher dans les combinaisons.

2voto

intrepidhero Points 21

Le Zen de Python dit "Explicite est mieux qu'implicites." J'ai trouvé cela très vrai dans ma propre expérience. Quand j'écris un morceau de code que j'ai penser à mon auto, "Vais-je comprendre ce que cela signifie d'une année à partir de maintenant?" Si la réponse est "non", alors il doit être ré-écrite ou documentée. L'on a accepté la réponse repose sur la mémorisation de la mise en œuvre de dict.chercher à savoir comment il va gérer le cas du coin. Depuis l'OP a 3 critères clairs, je serait plutôt de documenter clairement dans une instruction if.

if nObject.TextString == "overall_weight" and \
    "Overall Weight" in self.var.jobDetails and \
    self.var.jobDetails["Overall Weight"] != "":
    nObject.TextString = self.var.jobDetails["Overall Weight"]
else:
    nObject.TextString = "N/A"

C'est certainement plus de commentaires... mais c'est une bonne chose. Il n'est pas question lors de la lecture de ce que le comportement de l'être.

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