web-dev-qa-db-ja.com

外側のスコープからのシャドウ名xyz

私はpycharmを使用していますが、コードに関連するすべてのエラー/警告がリストされています。私はそれらの大部分を理解していますが、この「外部スコープからのシャドウ名xyz」についてはわかりません。これに関するいくつかのSO投稿: 外部スコープで定義されたシャドウイングの名前はどれほど悪いですか? しかし、彼らはグローバル変数にアクセスしているようです。

私の場合、私の__main__関数にはいくつかの変数名があり、別の関数を呼び出していますsample_funcこれらの変数名(主にループ変数名)を再び使用します。私は別の機能に属しているため、これらの変数のスコープはローカルであると想定していますが、そうでない場合は警告が示唆されるようです。

何かご意見は?参照用のコードを次に示します。

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

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

警告は、内部スコープでこれらの名前を再利用することにより、導入する潜在的な危険性に関するものです。バグを見逃す可能性があります。たとえば、これを考えます

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

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

同じ名前を使用したため、関数内のスペルミスはエラーになりません。

コードが非常に単純な場合、結果なしでこのタイプのものを使用できます。ただし、より複雑なコードでのミスを避けるために、これらの「ベストプラクティス」を使用することをお勧めします。

13
mehtunguh

Sample_funcの内部にいる場合、メイン関数のifブランチ内のコードは実際にはスコープ内にあります。変数xから読み取ることができます(試してみてください)。あまり気にしないので大丈夫なので、前進するためのいくつかのオプションがあります。

1)Pycharmのシャドウ警告を無効にします。正直なところ、これは最も簡単であり、コーダーの経験に応じて、おそらく最も理にかなっています(比較的新しい場合は、これを行いません)。

2)メインコードをメイン関数に配置します。これはおそらく、あらゆる生産レベルのコードに最適なソリューションです。 Pythonはあなたがやりたいように物事を行うのに非常に優れているので、trapに陥らないように注意する必要があります。モジュールを構築する場合、モジュールレベルで多くのロジックを代わりに、次のようなものが役立つ場合があります。

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 __name__ == '__main__':
    main()

3)より広い範囲で使用しているのと同じ変数名を使用しないでください。これは強制するのがかなり難しく、#1の反対です。

12
Ned Rockson

リンクされた質問で説明されているように、それは単に警告です。問題を引き起こす可能性がありますが、場合によってはxは関数に対してローカルです。 if __name__ == "__main__":内のxがグローバルにあるため、警告が表示されます。関数のxには影響しないので、警告について心配する必要はありません。

1

私はこれが古いスレッドであり、これは質問者が見つけようとしている問題には適切ではないことを知っていますが、PyCharmが私に「外側のスコープからのシャドウ名」メッセージを表示する理由の答えを探していましたif/Elifステートメントブロック...

関数の開始時にいくつかのグローバル変数名を大文字にしたが、関数のさらに下のif/Elifブロックでは小文字を使用したことがわかりました。

私が知っている学校の少年のエラーですが、これを修正すると、PyCharmの「外側のスコープからのシャドウ名」メッセージが消え、変数が灰色で表示されなくなりました...

だから私が学んだ教訓は、このPyCharmメッセージは変数名の大文字/小文字エラーのような単純な何かによって引き起こされる可能性があるということです...

私はインデントに問題があり、これが問題を引き起こしていると思っていたので、関数を3つの関数に分割して「シャドウ...」エラーを削除するかどうかを確認しているときに問題を認識しました!

これは、なぜこのエラーが発生するのか疑問に思っている初心者を助けるかもしれません:-)

0
Mark Smith