LoginSignup
45
40

More than 1 year has passed since last update.

Pythonで全モジュール共通のグローバル変数を扱う方法

Posted at

Pythonのグローバル変数

Pythonを使っていると、モジュール間共通のグローバル変数を使いたくなるシーンがあります。

このグローバル変数がとても扱いにくく
関数内からグローバル変数を書き換える場合、
使用前にglobalで変数を宣言しなければいけません。

main.py
global val1

def func1():
    global val1
    val1 = 100

def main():
   global val1
   func1()
   print(val1)

扱う変数の量が増えると、行頭のglobal宣言だけで数行埋まってしまいます。

プログラムをクラス化すれば良いのですが、Pythonではクラス変数の前にself.をつけなければいけないという制約があるため、コードが冗長になってしまいます。

また、モジュール外から他のモジュールのグローバル変数にアクセスしようとしても、思うようにいきません。

my_function.py
def func1():
    global val1
    val1 = 100
main.py
from my_function import *
global val1

def main():
   func1()
   print(val1)

このように書いてもグローバル変数を別モジュールから書き換えることが出来ません。

共通のファイルをインポートしてas gとする

これらの問題を解決する、とっておきの方法を思いつきました。

global_value.pyという中身空っぽのファイルを作成します(名前は何でも良いです)

global_value.py
#中身は空っぽ

使う側で、それをgとしてimportします
そして、グローバル変数をg.val1のように使用します。

my_function.py
import global_value as g

def func1():
    g.val1 = 1
main.py
import my_function
import global_value as g

def main():
   func1()
   print(g.val1)

こうすることでglobalの宣言は一切必要なくなり
g.をつけた変数はグローバル変数として扱えるようになります。

この変数は、他のモジュールからでも、クラス内からでも自由にアクセスできます。

変数名はやや冗長になりますが、ローカルとグローバルを明示する前置詞として働くため、プラスの効果も大きいと思います。

グローバル変数のメリット

Pythonはスクリプト言語です。

スクリプト言語は遅いだの、レベルが低いだの難癖を付けられがちですが
他の言語にはない強力な機能が用意されています。

それが、文字列をコードとして扱えるeval関数とexec関数です。

exec("g.val=100")

とすれば、g.valの値を100に書き換えることが出来ます。

これがtkinterと変数の同期処理で輝きます。

tkinterウィジェットを管理する辞書のキー値に変数名を用いることで決まったループ処理1つで変数とGUIの同期ができます。

my_gui.py
widgets = dict()
widgets["g.val1"] = widget1
widgets["g.val2"] = widget2
widgets["g.val3"] = widget3

def UpdateValue():
    for key in widgets.keys():
        exec(key+"="+str(widgets[key].data.get()))


実際はウィジェットクラスに適切な文字列を返すget_data_textメソッドを用意したほうが良いです。

この壁になっていたのが、グローバル変数問題でした。

どうにかしてウィジェットクラス内部から、メインプログラムのグローバル変数を書き換えられないかと悩んでいたら、この方法を思いつきました。

これが、誰かのお役に立てば幸いです。

45
40
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
40