Je viens de passer à Pycharm et je suis très heureux de tous les avertissements et astuces qu'il me donne pour améliorer mon code. Sauf pour celui-ci que je ne comprends pas:
This inspection detects shadowing names defined in outer scopes.
Je sais que c'est une mauvaise pratique d'accéder aux variables depuis la portée externe, mais quel est le problème avec l'observation de la portée externe?
Voici un exemple, où Pycharm me donne le message d'avertissement:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
python
coding-style
pycharm
Framester
la source
la source
Réponses:
Pas grand-chose dans votre extrait ci-dessus, mais imaginez une fonction avec quelques arguments supplémentaires et quelques lignes de code supplémentaires. Ensuite, vous décidez de renommer votre
data
argument commeyadda
mais manquez l'un des endroits où il est utilisé dans le corps de la fonction ... Désormais sedata
réfère au global, et vous commencez à avoir un comportement étrange - où vous auriez beaucoup plus évidentNameError
si vous ne le faisiez pas avoir un nom globaldata
.Souvenez-vous également qu'en Python, tout est un objet (y compris les modules, les classes et les fonctions), il n'y a donc pas d'espaces de noms distincts pour les fonctions, les modules ou les classes. Un autre scénario consiste à importer une fonction
foo
en haut de votre module et à l'utiliser quelque part dans le corps de votre fonction. Ensuite, vous ajoutez un nouvel argument à votre fonction et le nommez - pas de chance -foo
.Enfin, les fonctions et types intégrés vivent également dans le même espace de noms et peuvent être masqués de la même manière.
Rien de tout cela n'est un problème si vous avez des fonctions courtes, un bon nom et une couverture décente, mais bien, parfois, vous devez maintenir un code moins que parfait et être averti de ces problèmes possibles pourrait aider.
la source
nonlocal
mot - clé pour rendre explicite le référencement externe (comme dans les fermetures). Notez que cela est différent de l'observation, car il n'observe pas explicitement les variables de l'extérieur.La réponse actuellement la plus votée et acceptée et la plupart des réponses ici manquent de pertinence.
Peu importe la durée de votre fonction ou la façon dont vous nommez votre variable de manière descriptive (pour, espérons-le, minimiser les risques de collision de noms potentiels).
Le fait que la variable locale de votre fonction ou son paramètre partage un nom dans la portée globale est complètement hors de propos. Et en fait, peu importe le soin avec lequel vous choisissez votre nom de variable locale, votre fonction ne peut jamais prévoir "si mon nom génial
yadda
sera également utilisé comme variable globale à l'avenir?". La solution? Ne vous en faites pas!La mentalité correcte est de concevoir votre fonction pour consommer les entrées de et uniquement à partir de ses paramètres dans la signature , de cette façon, vous n'avez pas besoin de vous soucier de ce qui est (ou sera) de portée mondiale, puis l'observation ne devient plus un problème.En d'autres termes, le problème de l'observation n'a d'importance que lorsque votre fonction doit utiliser la même variable locale ET la variable globale. Mais vous devez éviter une telle conception en premier lieu. Le code de l'OP n'a PAS vraiment un tel problème de conception. C'est juste que PyCharm n'est pas assez intelligent et il émet un avertissement au cas où. Donc, juste pour rendre PyCharm heureux, et aussi pour rendre notre code propre, voir cette solution citant la réponse de silyevsk pour supprimer complètement la variable globale.
C'est la bonne façon de "résoudre" ce problème, en corrigeant / supprimant votre problème global, et non en ajustant votre fonction locale actuelle.
la source
print_data
EST une variable globale. Pensez-y ...Une bonne solution de contournement dans certains cas peut être de déplacer le code vars + vers une autre fonction:
la source
Cela dépend de la durée de la fonction. Plus la fonction est longue, plus il est probable que quelqu'un la modifiant à l'avenir écrira
data
pensant que cela signifie le global. En fait, cela signifie le local, mais comme la fonction est si longue, il n'est pas évident pour eux qu'il existe un local portant ce nom.Pour votre exemple de fonction, je pense que l'observation du global n'est pas mal du tout.
la source
Faites ceci:
la source
la source
data
, le tout dans quelques centaines de lignes de code?data
c'est un nom local dans cette fonction, donc je ne me soucie même pas de vérifier / me souvenir si un global du même nom existe , et encore moins ce qu'il contient.False
- si vous ne définissez pas, mais juste essayer d'utiliserdata
, il regarde à travers champs jusqu'à ce qu'il en trouve un, il ne trouve mondialdata
.data = [1, 2, 3]; def foo(): print(data); foo()
J'aime voir une coche verte dans le coin supérieur droit de pycharm. J'ajoute les noms de variables avec un trait de soulignement juste pour effacer cet avertissement afin que je puisse me concentrer sur les avertissements importants.
la source
Il ressemble à un modèle de code 100% pytest
voir:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
J'ai eu le même problème, c'est pourquoi j'ai trouvé ce post;)
Et il avertira
This inspection detects shadowing names defined in outer scopes.
Pour résoudre ce problème, déplacez simplement votre
twitter
appareil./tests/conftest.py
Et retirez le
twitter
luminaire comme dans./tests/test_twitter2.py
Ce sera heureux QA, Pycharm et tout le monde
la source