9
votes

Pourquoi est-ce une mauvaise idée de modifier les sections locales à Python?

lié ​​à cette réponse Ici . Local 'doc ici.

Les DOCS mentionnent que le dictionnaire ne doit pas changer, pas sûr de ce que cela signifie mais que locals () est applicable dans les rapports de laboratoire où les données ne changeront pas, par exemple dans des mesures?


0 commentaires

5 Réponses :


3
votes

de Plongez dans Python

locaux est une fonction qui retourne un Dictionnaire, et ici vous définissez un valeur dans ce dictionnaire. Tu pourrais pense que cela changerait la valeur de la variable locale x à 2, mais il ne le fait pas. les habitants ne sont pas réellement renvoyer l'espace de noms local, il renvoie une copie. Alors changer cela ne fait rien à la valeur des variables dans le Espace de noms local.


1 commentaires

Qui est inexact: locals () ne renvoie pas toujours une copie. Cependant, les cas où modifier locaux () ont effectivement un effet sont un détail de mise en œuvre et ne faisant pas partie de la définition de langue afin de ne pas dépendre de ce comportement.



10
votes

Quelle documentation dit que lorsque vous avez une variable locale X code> et do locaux () ['x'] = 42 code>, puis x code > peut toujours pointer sur l'ancien objet.

def foo():
    x = 0xABCD
    locals()['x'] = 42
    print(x)

foo()


3 commentaires

Y a-t-il une raison pour laquelle cela n'est pas possible? J'essaie littéralement de faire quelque chose comme celui-ci en combinaison avec EXEC / EVAL, mais cela n'est pas possible. Pourquoi Python 3.6 E.G. Ne me laisse pas changer la variable (s) précédente (s)?


@Pimathclanguage parce que vous êtes presque certainement Vous n'avez pas à faire cela . Il n'y a presque jamais de bonne affaire pour altérer dynamiquement l'espace de noms local et, puisque vous permettant de le faire empêcher une optimisation de Python 3 (l'espace de noms local n'est plus un dict mais un tableau pour un look plus rapide -UPS), alors les concepteurs de langue ont décidé qu'il n'était pas assez important de vous laisser faire ça


Une solution de contournement extrêmement hacky et laid est décrite dans Comment convertir ce code Python 2.7 en Python 3?



1
votes

La modification est une mauvaise idée car la documentation (que vous liez) dit explicitement de ne pas:

Note: Le contenu de ce dictionnaire ne doit pas être modifié; Les changements peuvent ne pas affecter les valeurs des variables locales et libres utilisées par l'interprète.

Vous n'avez plus besoin de raison que cela.

Si vous l'utilisez d'une manière qui ne modifie pas de variables, tout ira bien, mais je voudrais interroger la conception et voir s'il existe une meilleure façon de faire ce que vous voulez.


Dans l'exemple spécifique, vous liez, les sections locales sont en réalité globales (), lorsque vous l'utilisez dans la portée mondiale d'un module. Cette utilisation très spécifique fonctionne maintenant et, bien que je m'attends à ce qu'il continue à fonctionner comme avec les globaux, vous pourriez aussi bien utiliser les globaux à la place.

Une solution encore plus propre est probablement, sans connaître le reste de votre conception, d'utiliser un dictionnaire OL régulier pour vos variables; Ensuite, utilisez des données ["x"] = valeur au lieu des globaux () ["x"] = valeur.


2 commentaires

Quand quelqu'un demande "Pourquoi les documents disent-ils que c'est une mauvaise idée", répondant en disant "parce que les Docs le disent" n'est pas une réponse utile ou informative.


@Glennmaynard: Il ne dit pas "pourquoi les Docs disent-ils", il demande "pourquoi est-ce une mauvaise idée". Comme il n'est pas en mesure de changer le comportement et les documents, l'avertissement des documents est beaucoup de justification pour ne pas modifier les valeurs - en particulier lorsqu'il y a deux travaux de contournement faciles (les deux mentionnés ci-dessus).



4
votes

Dans l'interprète CPPHON, les variables locales peuvent provenir de plusieurs endroits (les détails de cela ne sont pas importants, mais cela a à voir avec la manière dont les variables sont stockées pour la fermeture). Le locals () La fonction recueille les noms et les valeurs de tous ces endroits, pour vous donner un accès pratique à eux au même endroit, mais comme il ne sait pas où une variable donnée est venue. ne peut pas le remettre. En d'autres termes, c'est une mauvaise idée parce que cela ne fonctionne pas.


0 commentaires

6
votes

Dans certains cas, l'appel à la localisation () renvoie les valeurs recueillies à partir de sources multiples, plutôt qu'un pointeur de la portée locale.

Exemple: lorsque dans une fonction Appel de fonction, les locaux () renvoient une combinaison de la portée globale et de la portée locale à la fonction. Dans ce cas, la modification de la sortie locale () ne modifiera pas la portée locale car elle utilise essentiellement une île. Il semble que les seuls cas où il ne fonctionne est des cas où sa sortie est la même que la production de globaux ().

Ainsi, en d'autres termes, vous souhaitez utiliser des globaux () ou trouver un moyen différent d'atteindre le même objectif.


3 commentaires

Qu'est-ce qu'une île?


@Antayhatchkins Je n'ai aucune idée de ce que je voulais dire par là. Hah!


Je suppose que "l'île" était censé faire référence à quelque chose isolé de ses environs. Donc, le dictionnaire locaux () détient des copies plutôt que des pointeurs sur les objets d'origine, c'est pourquoi modifier locaux () ne modifie pas les objets d'origine.