web-dev-qa-db-ja.com

Pythonで「グローバル」ステートメントを使用しますか?

Pythonglobalステートメント( "Pythonスコープ" )に関する質問を読んでいたそして、私がPython初心者(globalをたくさん使用したとき) )そして、最近、数年後、私はそれをまったく使用しないのですが、少し「非Pythonic」だとさえ考えています。

このステートメントをPython?で使用していますか?時間の経過とともに使用方法が変わりましたか?

次のようなコンテキストで「グローバル」を使用します。

_cached_result = None
def myComputationallyExpensiveFunction():
    global _cached_result
    if _cached_result:
       return _cached_result

    # ... figure out result

    _cached_result = result
    return result

私が「グローバル」を使用するのは、それが理にかなっており、機能の読者に何が起こっているのかが明確だからです。また、このパターンがあることも知っています。これは同等ですが、読者により多くの認知的負荷をかけます。

def myComputationallyExpensiveFunction():
    if myComputationallyExpensiveFunction.cache:
        return myComputationallyExpensiveFunction.cache

    # ... figure out result

    myComputationallyExpensiveFunction.cache = result
    return result
myComputationallyExpensiveFunction.cache = None
56
Jerub

プロダクションで3年以上Pythonを使用し、5年以上にわたってPython私が変更する必要がある状態はクラスに存在するか、「グローバル」状態がある場合は、グローバルキャッシュのような共有構造にあります。

15
ironfroggy

関数がグローバルに使用される変数を作成または設定する状況で使用しました。ここではいくつかの例を示します。

discretes = 0
def use_discretes():
    #this global statement is a message to the parser to refer 
    #to the globally defined identifier "discretes"
    global discretes
    if using_real_hardware():
        discretes = 1
...

または

file1.py:
    def setup():
        global DISP1, DISP2, DISP3
        DISP1 = grab_handle('display_1')
        DISP2 = grab_handle('display_2')
        DISP3 = grab_handle('display_3')
        ...

file2.py:
    import file1

    file1.setup()
    #file1.DISP1 DOES NOT EXIST until after setup() is called.
    file1.DISP1.resolution = 1024, 768
10
Adam Rossmiller

私の見解では、pythonコードでグローバル変数を使用する必要があると感じたらすぐに、少し停止してコードのリファクタリングに取り組む絶好の機会です。
globalをコードに入れ、リファクタリングプロセスを遅らせることは、締め切りが近い場合は有望に聞こえるかもしれませんが、信じてください。なんらかの奇妙な理由でコードが機能しなくなったように、デバッグする必要があります。これらのglobal変数のいくつかに遭遇すると、それらは混乱するだけです。

ですから、正直に言って、たとえそれが許可されていても、私はそれを使うことを避けることができる限り多くします。たとえそれがあなたのコードの周りの単純なクラスビルドを意味するとしても。

8
kender

コマンドラインスクリプトと「optparse」のグローバルオプションに使用します。

my main()は引数を解析し、それらをスクリプトの機能を果たす関数に渡しますが、提供されたオプションをグローバルな「opts」辞書に書き込みます。

シェルスクリプトオプションは「リーフ」の動作を微調整することが多く、すべての引数リストに「opts」ディクショナリをスレッド化するのは不便です(そして不必要です)。

3
Mike McCabe

オブジェクトが非ローカル状態を持つ好ましい方法であるため、グローバルはほとんど必要ありません。私は、今後の非ローカル修飾子が広く使用されるとは考えていません。ほとんどの場合、lispersが文句を言うのをやめるためにそこにあると思います:-)

3
JacquesB

私はそれを避け、実動コードでそれを禁止する pylint ルールさえ持っています。私は実際、それはまったく存在すべきではないと考えています。

2
André

状態を共有するスレッドで便利です(ロック機構を使用して)。

ただし、使用することはめったにありません。

2
Corey Goldberg

一度だけのタスクを自動化するために、クイック&ダーティな使い捨てスクリプトで使用しました。それよりも大きいもの、または再利用する必要があるものは、もっとエレガントな方法を見つけるでしょう。

2
Kena

まれに。私はまだその使用法を見つけていません。

2
hydrapheetz

一回か二回。しかし、リファクタリングの出発点は常に良いものでした。

1
zgoda

私がそれを避けることができれば、いいえ。そして、私の知る限り、それを避ける方法は常にあります。しかし、私はそれがまったく役に立たないと言っているわけではありません

0
rhymes