Comment réaliser des variables variables en Python?
Voici une entrée manuelle détaillée, par exemple: Variables variables
J'ai entendu dire que c'est une mauvaise idée en général cependant, et c'est un trou de sécurité en Python. Est-ce vrai?
Comment réaliser des variables variables en Python?
Voici une entrée manuelle détaillée, par exemple: Variables variables
J'ai entendu dire que c'est une mauvaise idée en général cependant, et c'est un trou de sécurité en Python. Est-ce vrai?
Réponses:
Vous pouvez utiliser des dictionnaires pour accomplir cela. Les dictionnaires sont des magasins de clés et de valeurs.
Vous pouvez utiliser des noms de clé de variable pour obtenir l'effet des variables de variable sans risque de sécurité.
Pour les cas où vous songez à faire quelque chose comme
une liste peut être plus appropriée qu'un dict. Une liste représente une séquence ordonnée d'objets, avec des indices entiers:
Pour les séquences ordonnées, les listes sont plus pratiques que dicts avec les touches entières, car les listes itération prennent en charge pour l'index, le découpage ,
append
et d' autres opérations qui requièrent une gestion clé maladroite avec un dict.la source
Utilisez la
getattr
fonction intégrée pour obtenir un attribut sur un objet par son nom. Modifiez le nom selon vos besoins.la source
Ce n'est pas une bonne idée. Si vous accédez à une variable globale, vous pouvez l'utiliser
globals()
.Si vous souhaitez accéder à une variable dans la portée locale, vous pouvez l'utiliser
locals()
, mais vous ne pouvez pas affecter de valeurs au dict renvoyé.Une meilleure solution consiste à utiliser
getattr
ou à stocker vos variables dans un dictionnaire, puis à y accéder par nom.la source
x = "foo"
et enlocals()["x"] = "bar"
utilisantprint x
donne la sortiebar
pour Jython 2.5.2. Cela a été testé avec un script d'automatisation à la demande in maximo .Chaque fois que vous souhaitez utiliser des variables variables, il est probablement préférable d'utiliser un dictionnaire. Donc au lieu d'écrire
vous écrivez
De cette façon, vous n'écraserez pas accidentellement des variables existantes (ce qui est l'aspect sécurité) et vous pouvez avoir différents "espaces de noms".
la source
Les nouveaux codeurs écrivent parfois du code comme ceci:
Le codeur se retrouve alors avec une pile de variables nommées, avec un effort de codage de O ( m * n ), où m est le nombre de variables nommées et n est le nombre de fois que ce groupe de variables doit être accédé (y compris la création ). Le débutant le plus astucieux observe que la seule différence dans chacune de ces lignes est un nombre qui change en fonction d'une règle, et décide d'utiliser une boucle. Cependant, ils se retrouvent bloqués sur la façon de créer dynamiquement ces noms de variables et peuvent essayer quelque chose comme ceci:
Ils constatent rapidement que cela ne fonctionne pas.
Si le programme nécessite des «noms» de variables arbitraires, un dictionnaire est le meilleur choix, comme expliqué dans d'autres réponses. Cependant, si vous essayez simplement de créer de nombreuses variables et que cela ne vous dérange pas de vous y référer avec une séquence d'entiers, vous recherchez probablement un
list
. Cela est particulièrement vrai si vos données sont homogènes, telles que les relevés de température quotidiens, les scores de quiz hebdomadaires ou une grille de widgets graphiques.Cela peut être assemblé comme suit:
Cela
list
peut également être créé en une seule ligne avec une compréhension:Dans les deux cas, le résultat est un remplissage
list
, avec le premier élément accédé avecmy_calculator.buttons[0]
, le suivant avecmy_calculator.buttons[1]
, et ainsi de suite. Le nom de la variable "base" devient le nom dulist
et l'identifiant variable est utilisé pour y accéder.Enfin, n'oubliez pas d'autres structures de données, telles que le
set
- c'est similaire à un dictionnaire, sauf que chaque "nom" n'a pas de valeur attachée. Si vous avez simplement besoin d'un "sac" d'objets, cela peut être un excellent choix. Au lieu de quelque chose comme ça:Vous aurez ceci:
Utilisez a
list
pour une séquence d'objets similaires, aset
pour un sac d'objets commandés arbitrairement ou adict
pour un sac de noms avec des valeurs associées.la source
Au lieu d'un dictionnaire, vous pouvez également utiliser à
namedtuple
partir du module collections, ce qui facilite l'accès.Par exemple:
la source
Si vous ne voulez utiliser aucun objet, vous pouvez toujours utiliser à l'
setattr()
intérieur de votre module actuel:la source
__dict__
Cependant, cela ne fonctionne pas avec la variable. Je me demande s'il existe un mécanisme général pour créer une dynamique variable globale.globals()
peut le faireLa
SimpleNamespace
classe peut être utilisée pour créer de nouveaux attributs avecsetattr
, ou sousSimpleNamespace
- classe et créer votre propre fonction pour ajouter de nouveaux noms d'attribut (variables).la source
Je réponds à la question: comment obtenir la valeur d'une variable étant donné son nom dans une chaîne? qui est fermé en double avec un lien vers cette question.
Si les variables en question font partie d'un objet ( une partie d'une classe par exemple) , alors certaines fonctions utiles pour atteindre ce sont exactement
hasattr
,getattr
etsetattr
.Ainsi, par exemple, vous pouvez avoir:
Ensuite, vous pouvez faire:
la source
Utilisation
globals()
Vous pouvez réellement affecter des variables à la portée globale de façon dynamique, par exemple, si vous voulez 10 variables accessibles sur une portée globale
i_1
,i_2
...i_10
:Cela affectera «a» à toutes ces 10 variables, bien sûr, vous pouvez également modifier la valeur dynamiquement. Toutes ces variables sont accessibles maintenant comme les autres variables déclarées globalement:
la source
Vous devez utiliser la
globals()
méthode intégrée pour obtenir ce comportement:la source
Le consensus est d'utiliser un dictionnaire pour cela - voir les autres réponses. C'est une bonne idée pour la plupart des cas, cependant, il y a de nombreux aspects qui en découlent:
Cela dit, j'ai implémenté un gestionnaire de variables variables -class qui fournit certaines des idées ci-dessus. Cela fonctionne pour python 2 et 3.
Vous utiliseriez la classe comme ceci:
Si vous souhaitez autoriser l'écrasement de variables de même type uniquement:
la source
J'ai essayé les deux en python 3.7.3, vous pouvez utiliser soit globals () ou vars ()
Référence:
https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936
la source
Tout ensemble de variables peut également être enveloppé dans une classe. Des variables "variables" peuvent être ajoutées à l'instance de classe pendant l'exécution en accédant directement au dictionnaire intégré via l'attribut __dict__.
Le code suivant définit la classe Variables, qui ajoute des variables (dans ce cas des attributs) à son instance pendant la construction. Les noms de variables sont tirés d'une liste spécifiée (qui, par exemple, aurait pu être générée par le code du programme):
la source