web-dev-qa-db-fra.com

Python: attribuer une valeur si aucune n'existe

Je suis un programmeur RoR nouveau sur Python. J'essaie de trouver la syntaxe qui me permettra de définir une variable sur une valeur spécifique uniquement si elle n'a pas déjà été affectée. En gros je veux:

# only if var1 has not been previously assigned

var1 = 4
42
Spencer

C'est un style de programmation très différent, mais j'essaie toujours de réécrire des choses qui ressemblent à

bar = None
if foo():
    bar = "Baz"

if bar is None:
    bar = "Quux"

dans juste:

if foo():
    bar = "Baz"
else:
    bar = "Quux"

C'est-à-dire que j'essaie d'éviter une situation où certains chemins de code définissent des variables, mais pas d'autres. Dans mon code, il n'y a jamais de chemin qui cause une ambiguïté sur l'ensemble des variables définies (en fait, je vais généralement plus loin et m'assure que les types sont les mêmes quel que soit le chemin du code ) Ce n'est peut-être qu'une question de goût personnel, mais je trouve ce schéma, bien qu'un peu moins évident lorsque je l'écris, beaucoup plus facile à comprendre lorsque je le lirai plus tard.

Vous devez initialiser les variables sur Aucune et ensuite le vérifier:

var1 = None
if var1 is None:
    var1 = 4

Ce qui peut être écrit en une ligne comme:

var1 = 4 if var1 is None else var1

ou en utilisant un raccourci (mais une vérification par rapport à Aucun est recommandée)

var1 = var1 or 4

alternativement, si rien n’est assigné à une variable, ce nom de variable n’existe pas et, par conséquent, l’utiliser plus tard soulèvera NameError, et vous pourrez également utiliser cette connaissance pour faire ce genre de chose.

try:
    var1
except NameError:
    var1 = 4

mais je déconseillerais cela.

79
Anurag Uniyal
var1 = var1 or 4

Le seul problème que cela pourrait avoir est que si var1 est une valeur de falsey, comme False ou 0 ou [], il choisira 4 à la place. Cela pourrait être un problème.

24
ubadub

Je viens aussi de Ruby alors j'adore la syntaxe foo ||= 7.

C'est la chose la plus proche que je puisse trouver.

foo = foo if 'foo' in vars() else 7

J'ai vu des gens faire ça pour un dict:

try:
    foo['bar']
except KeyError:
    foo['bar'] = 7

padate: Cependant, j'ai récemment trouvé ce petit bijou:

foo['bar'] = foo.get('bar', 7)

Si vous aimez cela, alors pour une variable régulière, vous pouvez faire quelque chose comme ceci:

vars()['foo'] = vars().get('foo', 7)
14
l__flex__l

La réponse de IfLoop (et le commentaire de MatToufoutu) fonctionnent très bien pour les variables autonomes, mais je voulais fournir une réponse à quiconque essayait de faire quelque chose de similaire pour des entrées individuelles dans des listes, des tuples ou des dictionnaires.

dictionnaires

existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3

Résultats {"spam": 1, "eggs": 2, "foo": 3}

Listes

existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else 
                existing_list + ["foo"]

Résultats ["spam", "eggs", "foo"]

Tuples

existing_Tuple = ("spam","eggs")
existing_Tuple = existing_Tuple if len(existing_Tuple)==3 else 
                 existing_Tuple + ("foo",)

Résultats ("spam", "eggs", "foo")

(N'oubliez pas la virgule dans ("foo",) pour définir un "single" Tuple.)

La solution de listes et de tuples sera plus compliquée si vous voulez faire plus que vérifier la longueur et ajouter à la fin. Néanmoins, cela donne une idée de ce que vous pouvez faire.

4
Alex P. Miller

Si vous voulez parler d'une variable au niveau du module, vous pouvez utiliser "globals":

if "var1" not in globals():
    var1 = 4

mais le plus commun Python est de l'initialiser pour dire None (en supposant que ce n'est pas une valeur acceptable)), puis de tester avec if var1 is not None.

1
6502