web-dev-qa-db-ja.com

PythonグローバルキーワードとPylintW0603

Pylint W0603の状態:

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

なんでそうなのかしら?関数内の不変のモジュール全体の変数を変更するPythonの方法は他にありますか?辞書のような可変変数内にそれらをパックすることをお勧めしますか?それとも、モジュール全体をクラスに変えますか?

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

20
Jovik

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

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

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

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

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

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

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

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!")

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

7
Ned Batchelder

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

0
mgilson