31

Pylint W0603 は次のように述べています。

グローバル ステートメントの使用。「global」ステートメントを使用してグローバル変数を更新するときに使用します。PyLint は、この使用法を思いとどまらせようとします。それはあなたがそれを使用できないという意味ではありません!

なぜそうなのだろうか?関数内の不変のモジュール全体の変数を変更する Pythonic の方法はありますか? 辞書などの可変変数内にパックすることをお勧めしますか? それとも、モジュール全体をクラスに変換しますか?

私の意見では、変数が「プライベート」であることが示唆された場合、この警告は消えるはずです (_ または _ の前に付けられます)。

4

4 に答える 4

35

グローバル変数を一般的に使用すると、プログラムのフローをトレースするため、メンテナンスが悪夢になる可能性があります。また、一部のモジュールが変数を読み取り、他のモジュールが変数の値を変更する前にその値に基づいて動作するため、奇妙なバグが発生することがあります。 (これは、関連のない3番目のモジュールで2つのimportステートメントを反転した結果である可能性があります)。グローバル変数に関するウィキペディアのエントリも参照してください。

これが、可変グローバル変数IMOを回避する必要がある理由であり、Pylintが警告を発行する理由です(おそらく、より多くの変数を発行する必要があります。globalキーワードの使用を検出することは、それらの一部を見つける簡単な方法です)。

誤解しないでください。グローバル変数を使用してはいけないと言っているのではありません。あなたがそれらを使用することを避けるべきであるということだけ。Pythonのグローバル変数には多くの正当なケースがあります。W0603を2つ以上入手しない限り、大丈夫です。

現在、Logilab(Pylintを保守している会社であり、私が以前働いていた場所)は、大量の複製と100以上の可変グローバル変数を使用して、50klocを超えるPythonコードの保守を引き継ぐ必要がありました。そして、これは地獄でした。

グローバル変数を回避するためのソリューションは次のとおりです。

  • 変数にアクセスする必要がある関数にパラメーターを追加する
  • クラス属性の使用
  • インスタンス属性の使用(必要な値をクラスのコンストラクターに渡すことにより)
  • プログラムの起動時に(環境変数、コマンドライン、構成ファイルなどを使用して)一度インスタンス化され、その後は変更されないようにビルドされた構成オブジェクトに、変更可能なグローバル値を一元化します。
于 2013-01-24T16:00:36.970 に答える
13

私はこれを置き換えます:

the_file = None

def open_the_file(fname):
    global the_file
    the_file = open(fname)

def write_to_the_file(data):
    the_file.write(data)

open_the_file("boo")
write_to_the_file("Hi!")

これとともに:

class FileProgram(object):
    def __init__(self):
        self.the_file = None

    def open_the_file(fname):
        self.the_file = open(fname)

    def write_to_the_file(data):
        self.the_file.write(data)

if __name__ == "__main__":
    prog = FileProgram()
    prog.open_the_file("boo")
    prog.write_to_the_file("Hi!")

「私の単純な作業には難しすぎる!」と言うかもしれません。それでは、プログラムで pylint を実行しないでください。プログラムが小さすぎて適切な構造を使用できないことを pylint に理解させることはできません。

于 2013-01-24T16:18:48.853 に答える
1

Pythonでは、このようなグローバルデータを共有するモジュールはほとんどシングルトンです。クラスで同じことを達成することも、実際にシングルトンが必要なsingleton理由があるかどうかを自問することもできます。シングルトンが必要ない場合は、通常のクラス(インスタンス)を使用します。シングルトンが必要な場合は、google / search SOを使用して、どのパターンが最適かを判断してください。たぶんあなたはモジュールが欲しいでしょう-ニッチがあります-そうでなければGuidoはずっと前にそれを言語から切り取っていたでしょう-そのニッチはたまたまかなり小さいです...global

于 2013-01-24T15:07:53.277 に答える