web-dev-qa-db-fra.com

Les ombres nomment xyz à partir de la portée externe

J'utilise pycharm et il répertorie toutes les erreurs/avertissements associés au code. Bien que je comprenne la plupart d’entre eux, je ne suis pas sûr de celui-ci "Shadows name xyz from scope externe". Il y a quelques SO messages à ce sujet: Quelle est la gravité des noms d'ombrage définis dans les portées externes? mais ils semblent alors accéder à une variable globale. 

Dans mon cas, ma fonction __main__ a quelques noms de variable, puis elle appelle une autre fonction sample_func qui utilise à nouveau ces noms de variable (principalement les noms de variable de boucle). J'assume parce que je suis dans une fonction différente, la portée de ces variables sera locale, mais l'avertissement semble suggérer le contraire. 

Des pensées? Pour votre référence, voici un code:

def sample_func():
    for x in range(1, 5):  --> shadows name x from outer scope
        print x

if __== "__main__":
    for x in range(1, 5):
        sample_func()
14
The Wanderer

L’avertissement concerne le danger potentiel que vous présentez en réutilisant ces noms sur des portées internes. Cela peut vous faire rater un bogue. Par exemple, considérons ceci

def sample_func(*args):
    smaple = sum(args) # note the misspelling of `sample here`
    print(sample * sample)

if __== "__main__":
    for sample in range(1, 5):
        sample_func()

Parce que vous avez utilisé le même nom, votre faute d'orthographe dans la fonction ne provoque pas d'erreur.

Lorsque votre code est très simple, vous vous en tirerez sans conséquences. Mais il est bon d'utiliser ces "meilleures pratiques" afin d'éviter des erreurs sur un code plus complexe.

10
mehtunguh

Le code à l'intérieur de votre branche if de votre fonction principale est réellement dans la portée lorsque vous êtes à l'intérieur de sample_func. Vous pouvez lire la variable x (l'essayer). C’est bien car vous ne vous en souciez pas vraiment, vous avez donc quelques options pour aller de l’avant.

1) Désactivez les avertissements d'observation dans pycharm. Honnêtement, c’est le plus simple et, selon votre expérience du programmeur, c’est probablement le plus logique (si vous êtes relativement nouveau, je ne le ferais pas).

2) Mettez votre code principal dans une fonction principale. C'est probablement la meilleure solution pour tout code de niveau de production. Python sait très bien faire les choses comme vous le souhaitez, vous devez donc faire attention à ne pas tomber dans des pièges. Si vous construisez un module, avoir beaucoup de logique au niveau du module peut vous mettre dans des situations difficiles. Au lieu de cela, quelque chose comme ce qui suit pourrait être utile:

def main():
    # Note, as of python 2.7 the interpreter became smart enough
    # to realize that x is defined in a loop, so printing x on this
    # line (prior to the for loop executing) will throw an exception!
    # However, if you print x by itself without the for loop it will
    # expose that it's still in scope. See https://Gist.github.com/nedrocks/fe42a4c3b5d05f1cb61e18c4dabe1e7a
    for x in range(1, 5):
        sample_func()

if __== '__main__':
    main()

3) N'utilisez pas les mêmes noms de variables que vous utilisez dans des domaines plus larges. C'est assez difficile à appliquer et c'est un peu l'opposé de # 1.

13
Ned Rockson

C'est juste un warning , comme expliqué dans la question liée, cela peut parfois poser problème, mais dans votre cas, x est local pour votre fonction. Vous recevez cet avertissement parce que la x dans votre if __== "__main__": est en globals. Cela n'aura aucun effet sur la x dans votre fonction, je ne m'inquiéterais donc pas de l'avertissement. 

1
Padraic Cunningham

Je sais que c'est un vieux fil et que cela ne convient pas au problème que le demandeur cherchait à résoudre, mais je cherchais une réponse à la question de savoir pourquoi PyCharm m'avait montré un message 'Nom de l'ombre de la portée extérieure' sur un complexe Bloc d'instructions if/Elif ...

Il s’avère que j’ai mis en majuscule des noms de variables globales au début de la fonction mais que j’utilisais les minuscules dans mon bloc if/Elif beaucoup plus bas dans la fonction.

Une erreur d'écolier, je le sais, mais une fois que j'ai corrigé cela, le message "Nom de l'ombre de la portée extérieure" dans PyCharm a disparu et les variables ont cessé de s'afficher comme grisées ...

La leçon que j'ai apprise est que ce message PyCharm peut être causé par quelque chose d'aussi simple qu'une erreur minuscule/majuscule dans un nom de variable ...

J'ai seulement réalisé le problème lorsque je divisais la fonction en trois fonctions pour voir si cela effacerait l'erreur "Ombres ...", car je pensais que j'avais un problème d'indentation et que c'était la cause du problème!

Cela peut aider un autre débutant qui se gratte la tête en se demandant pourquoi il a cette erreur :-)

0
Mark Smith