529 votes

Déterminer si une variable est définie dans Python

Comment savoir si une variable a été définie à un endroit particulier du code au moment de l'exécution ? Ce n'est pas toujours évident car (1) la variable peut être définie de manière conditionnelle, et (2) la variable peut être supprimée de manière conditionnelle. Je cherche quelque chose comme defined() en Perl ou isset() en PHP ou defined? en Ruby.

if condition:
    a = 42

# is "a" defined here?

if other_condition:
    del a

# is "a" defined here?

12 votes

89 votes

S'il vous plaît, s'il vous plaît, s'il vous plaît, ne définissez pas une variable de manière "conditionnelle". C'est juste une conception épouvantable, horrible. Toujours, toujours, toujours, toujours prévoir tous les chemins logiques. S'il vous plaît, ne continuez pas à faire cela.

2 votes

+1 à la réponse de S.Lott. Le fait qu'il existe un moyen de le faire ne signifie pas que vous devez l'utiliser dans un nouveau projet.

766voto

Alex Martelli Points 330805
try:
    thevariable
except NameError:
    print("well, it WASN'T defined after all!")
else:
    print("sure, it was defined.")

78 votes

@Aaron : Il existe de nombreux cas où vous ne savez pas si une variable est définie. Vous pouvez remanier le code pour éviter cela dans de nombreux cas, mais pas dans tous. La solution d'Alex est correcte et c'est la meilleure lorsque le remaniement du code n'est pas possible pour certaines raisons. Il n'y a pas beaucoup d'informations dans la question, donc je crois que seule la personne qui l'a posée peut choisir la meilleure façon de traiter son cas.

148 votes

@Aaron, "devrait" est un mot de 4 lettres -- par exemple, aucun conducteur ne "devrait" jamais dépasser la limite de vitesse, mais cela ne signifie pas que vous ne prenez pas toutes les précautions appropriées et nécessaires contre ceux qui le font néanmoins. Maintenir un code hérité fragile, sous testé avec une conception quelque peu brisée que vous avez hérité de quelqu'un d'autre est une réalité de la vie, et ceux qui ne peuvent penser qu'à une réécriture big-bang à partir de zéro plutôt que de manière prudente et incrémentale ont besoin de relire l'essai de Joel qui date de 9 ans joelonsoftware.com/articles/fog0000000069.html .

10 votes

@S.Lott Les gens l'utilisent pour maintenir une compatibilité descendante. Cherchez NameError dans le code source de Python 3.1. Il existe de nombreux cas où "try : var_name except NameError : something_else" est utilisé. Voici quelques endroits où il est utilisé : CSV ( svn.python.org/projets/python/trunk/Lib/csv.py ) et dans la bibliothèque ElementTree ( svn.python.org/projets/python/trunk/Lib/xml/etree/ ).

451voto

gnibbler Points 103484

'a' in vars() or 'a' in globals()

si vous voulez être pédant, vous pouvez aussi vérifier les builtins
'a' in vars(__builtins__)

35 votes

Cela devrait être la réponse, je crois. stackoverflow.com/questions/843277/

3 votes

C'est une réponse très idiomatique. Il y a ici un cas d'utilisation important pour les cartes, par exemple, if "prop2" in {"prop0": None, "prop1": None}:

0 votes

Cette réponse fonctionne également pour détecter les membres autres que les variables, tels que les fonctions, les classes et les modules.

161voto

divegeek Points 1754

Je pense que c'est mieux d'éviter la situation. C'est plus propre et plus clair à écrire :

a = None
if condition:
    a = 42

9 votes

Si vous souhaitez procéder de cette manière, vous devez rendre la valeur initiale unique afin de pouvoir la distinguer d'un paramètre quelconque. a a None ie. UNDEFINED=object();a=UNDEFINED alors vous pouvez tester avec a is not UNDEFINED

19 votes

C'est une utilisation courante de None. C'est littéralement la signification sémantique de None - c'est rien, nada, zip. Il existe, mais n'a "aucune valeur". L'utilisation d'une valeur autre que None est utile si None peut apparaître dans un devoir, etc., mais ce n'est pas si courant qu'éviter None devrait être une pratique standard. Par exemple, dans la question, a ne peut être que 42 ou indéfini. Le fait de remplacer la valeur indéfinie par None n'entraîne aucune perte d'information.

6 votes

C'est LA méthode, je ne sais pas pourquoi les gens pensent qu'il faut utiliser une construction try/except longue et sale pour y parvenir. C'est également très utile lorsque vous utilisez des args de mots-clés dans des fonctions de membres de classe où vous ne voulez pas coder en dur les valeurs par défaut dans la liste des paramètres (vous définissez simplement la valeur par défaut comme un membre de classe).

24voto

sc45 Points 801
try:
    a # does a exist in the current namespace
except NameError:
    a = 10 # nope

11 votes

Les exceptions ne doivent être utilisées que dans des cas exceptionnels. Voir cette discussion

22 votes

@einpoklum C'est vrai pour la plupart des langages, mais en Python, les exceptions sont utilisées plus souvent, voir par ex. stackoverflow.com/questions/3086806

4 votes

Hmm, étrange mais vrai, apparemment. Je pense toujours que ce n'est pas une bonne idée (TM) mais, bon, on ne peut pas discuter des coutumes de la communauté.

6voto

Denis Otkidach Points 13111

Pour ce cas particulier, il est préférable de faire a = None au lieu de del a . Cela va décrémenter le nombre de références à l'objet a a été (le cas échéant) assigné à et n'échouera pas quand a n'est pas défini. Notez que del n'appelle pas directement le destructeur d'un objet, mais le libère de la variable. Le destructeur d'un objet est appelé lorsque le nombre de références est devenu nul.

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