Est-ce une mauvaise pratique d'utiliser le format suivant lorsque my_var
peut être Aucun?
if my_var and 'something' in my_var:
#do something
Le problème est que 'something' in my_var
lancera une TypeError si my_var est None.
Ou devrais-je utiliser:
if my_var:
if 'something' in my_var:
#do something
ou
try:
if 'something' in my_var:
#do something
except TypeError:
pass
Pour reformuler la question, laquelle des méthodes ci-dessus est la meilleure pratique dans Python (le cas échéant)?
Les alternatives sont les bienvenues!
Il est sûr de dépendre de l'ordre des conditions ( référence Python ici ), en particulier en raison du problème que vous signalez - il est très utile de pouvoir court-circuiter l'évaluation qui pourrait causer des problèmes dans une chaîne de conditionnels.
Ce type de code apparaît dans la plupart des langues:
IF exists(variable) AND variable.doSomething()
THEN ...
Oui c'est sûr, c'est explicitement et très clairement défini dans la référence du langage:
L'expression
x and y
évalue d'abordx
; six
estfalse
, sa valeur est retournée; sinon,y
est évalué et la valeur résultante est renvoyée.L'expression
x or y
évalue d'abordx
; six
est vrai, sa valeur est retournée; sinon,y
est évalué et la valeur résultante est renvoyée.
Je suis peut-être un peu pédant ici, mais je dirais que la meilleure réponse est
if my_var is not None and 'something' in my_var:
#do something
La différence étant la vérification explicite de None
, plutôt que la conversion implicite de my_var
à True
ou False
.
Bien que je sois sûr que dans votre cas, la distinction n'est pas importante, dans le cas plus général, il serait tout à fait possible que la variable ne soit pas None
mais qu'elle soit toujours évaluée à False
, par exemple une valeur entière de 0
ou une liste vide.
Donc, contrairement à la plupart des affirmations des autres affiches selon lesquelles c'est sûr, je dirais que c'est sûr tant que vous êtes explicite. Si vous n'êtes pas convaincu, pensez à cette classe très artificielle:
class Contrived(object):
def __contains__(self, s):
return True
def __nonzero__(self):
return False
my_var = Contrived()
if 'something' in my_var:
print "Yes the condition is true"
if my_var and 'something' in my_var:
print "But this statement won't get reached."
if my_var is not None and 'something' in my_var:
print "Whereas this one will."
Oui, je sais que ce n'est pas un exemple réaliste, mais des variations se produisent dans le code réel, en particulier lorsque None
est utilisé pour indiquer un argument de fonction par défaut.
C'est parfaitement sûr et je le fais tout le temps.
J'irais avec le try/except, mais cela dépend de ce que vous savez sur la variable.
Si vous vous attendez à ce que la variable existe la plupart du temps, alors un essai/except est moins d'opérations. Si vous vous attendez à ce que la variable soit None la plupart du temps, alors une instruction IF sera moins d'opérations.
Ce n'est pas aussi simple. En tant que mec C #, j'ai l'habitude de faire quelque chose comme:
if(x != null && ! string.isnullorempty(x.Name))
{
//do something
}
Ce qui précède fonctionne très bien et est évalué comme prévu. Cependant, dans VB.Net, les résultats suivants produiraient un résultat auquel vous ne vous attendiez pas:
If Not x Is Nothing **And** Not String.IsNullOrEmpty(x.Name) Then
'do something
End If
Ce qui précède générera une exception. La syntaxe correcte doit être
If Not x Is Nothing **AndAlso** Not String.IsNullOrEmpty(x.Name) Then
'do something
End If
Notez la différence très subtile. Cela m'a dérouté pendant environ 10 minutes (beaucoup trop long) et c'est pourquoi les mecs C # (et autres) doivent être très prudents lors du codage dans d'autres langages.