Existe-t-il un équivalent Python de l'opérateur Ruby ||=
("définir la variable si la variable n'est pas définie")?
Exemple en rubis:
variable_not_set ||= 'bla bla'
variable_not_set == 'bla bla'
variable_set = 'pi pi'
variable_set ||= 'bla bla'
variable_set == 'pi pi'
Non, le remplacement est:
try:
v
except NameError:
v = 'bla bla'
Cependant, vouloir utiliser cette construction est un signe de flux de code trop compliqué. Habituellement, vous feriez ce qui suit:
try:
v = complicated()
except ComplicatedError: # complicated failed
v = 'fallback value'
et ne jamais savoir si v
est défini ou non. S'il s'agit d'une des nombreuses options pouvant être définies ou non, utilisez un dictionnaire et sa méthode get
qui autorise une valeur par défaut.
Je suis surpris que personne ne propose cette réponse. Ce n'est pas aussi "intégré" que le ||=
de Ruby mais c'est fondamentalement équivalent et reste un one-liner:
foo = foo if 'foo' in locals() else 'default'
Bien sûr, locals()
n’est qu’un dictionnaire, vous pouvez donc faire:
foo = locals().get('foo', 'default')
J'utiliserais
x = 'default' if not x else x
Beaucoup plus court que toutes vos alternatives suggérées ici, et droit au but. Lisez, "définissez x par défaut si x n'est pas défini, sinon conservez-le comme x." Si vous avez besoin que None
, 0
, False
ou ""
soient des valeurs valides, vous devrez toutefois modifier ce comportement, par exemple:
valid_vals = ("", 0, False) # We want None to be the only un-set value
x = 'default' if not x and x not in valid_vals else x
Ce genre de chose ne demande qu’à être transformé en une fonction que vous pouvez utiliser partout facilement:
setval_if = lambda val: 'default' if not val and val not in valid_vals else val
à quel point, vous pouvez l'utiliser comme:
>>> x = None # To set it to something not valid
>>> x = setval_if(x) # Using our special function is short and sweet now!
>>> print x # Let's check to make sure our None valued variable actually got set
'default'
Enfin, s'il vous manque vraiment la notation Ruby Infix, vous pouvez surcharger ||=|
(ou quelque chose de similaire) en suivant le hack de ce type: http://code.activestate.com/recipes/384122-infix-operators/
Non, ne pas savoir quelles variables sont définies est un bug, pas une fonctionnalité de Python.
Utilisez des dict à la place:
d = {}
d.setdefault('key', 1)
d['key'] == 1
d['key'] = 2
d.setdefault('key', 1)
d['key'] == 2
(je ne peux pas faire de commentaire ou je voudrais simplement faire cela) Je pense que la suggestion de vérifier les sections locales ci-dessus n'est pas tout à fait correcte. CA devrait etre:
foo = foo if 'foo' in locals() or 'foo' in globals() else 'default'
être correct dans tous les contextes.
Cependant, malgré ses votes positifs, je ne pense même pas que ce soit un bon analogue à l'opérateur Ruby. Puisque l'opérateur Ruby permet plus qu'un simple nom à gauche:
foo[12] ||= something
foo.bar ||= something
La méthode d'exception est probablement l'analogue le plus proche.
Je le fais habituellement de la manière suivante:
def set_if_not_exists(obj,attr,value):
if not hasattr(obj,attr): setattr(obj,attr,value)
Je pense que ce que vous recherchez, si vous cherchez quelque chose dans un dictionnaire, est la méthode setdefault
:
(Pdb) we=dict()
(Pdb) we.setdefault('e',14)
14
(Pdb) we['e']
14
(Pdb) we['r']="p"
(Pdb) we.setdefault('r','jeff')
'p'
(Pdb) we['r']
'p'
(Pdb) we[e]
*** NameError: name 'e' is not defined
(Pdb) we['e']
14
(Pdb) we['q2']
*** KeyError: 'q2' (Pdb)
La chose importante à noter dans mon exemple est que la méthode setdefault
modifie le dictionnaire si et seulement si la clé à laquelle la méthode setdefault
fait référence n'est pas présente.
Il existe une affectation conditionnelle dans Python 2.5 et les versions ultérieures - la syntaxe n’est pas très évidente et est donc facile à manquer. Voici comment vous le faites:
x = true_value if condition else false_value
Pour plus de référence, consultez le Python 2.5 docs .