Rich Richer Richest

カメラ / レンズ / 写真 / 名古屋 / ライフハック / 思い付き / 猫 ライフログで暮らしをRichに!

【備忘録】Python global 変数の扱い方でずっこけた

f:id:mocchipa:20200321161500p:plain

Raspberry pi でプロトタイプ的なものを作ってます。

今日つまずいていたところをシェアします。

下記のようなソースを書いたところ。

FLG_EXE = False
FLG_ART = False
 
def display_show():
    if FLG_EXE :
        return
    if FLG_ART :
        wb.open("Arart.html",0)
        FLG_EXE = True
    else :
        wb.open("Normal.html" , 0)
        FLG_EXE = True
try:
    while True:
        display_show()
        
        if GPIO.input(SW_ART) == GPIO.HIGH
            FLG_ART = True
            FLG_EXE = False
 
        if GPIO.input(SW_RST) == GPIO.HIGHT
            FLG_ART = False
            FLG_EXE = True
    time.sleep(0.1)
excep Exception as e:
    print(e)
    GPIO.cleanup()

 

下記のエラーが表示されました。

local variable 'FLG_EXE'  eferenced before assignment

print('check point 01')や、print(FLG_EXE)などを埋めまくって調査したおところ、def display_show() 内の最初の FLG_EXE を参照しにいってこけているようでした。

 

ググった所次の記事が役立ちました。

teratail.com

どうやら def 関数内でグローバル変数を使うときはglobalと明示してやらないとlocal変数として扱われてしまう事があるようです。

つまりはこのようにしないとこのエラーは発生するみたいです。

def display_show():
 #グローバル変数ですよと明示
    global FLG_EXE
    global FLG_ART
 
    if FLG_EXE :
        return
    if FLG_ART :
        wb.open("Arart.html",0)
        FLG_EXE = True
    else :
        wb.open("Normal.html" , 0)
        FLG_EXE = True

 

 ただし、こういうのはバグを生みやすい書き方らしいので、アドバイスに従い下記に変更しました。

 

FLG_EXE = False
FLG_ART = False
 
def display_show(flg_art):
    if flg_art :
        wb.open("Arart.html",0)
    else :
        wb.open("Normal.html" , 0)
    return True
 
try:
    while True:
        if FLG_EXE == False
            FLG_EXE = display_show(FLG_ART)
 
            #この処理を入れておかないとブラウザが開きまくる。
            #表示まちで1秒待つ
            time.sleep(1)
 
        if GPIO.input(SW_ART) == GPIO.HIGH :
            FLG_ART = True
            FLG_EXE = False
 
        if GPIO.input(SW_RST) == GPIO.HIGHT :
            FLG_ART = False
            FLG_EXE = True
    time.sleep(0.1)
except Exception as e:
    print(e)
    GPIO.cleanup()

 グローバル変数を弄るのではなく、関数の引数と返り値で処理するやり方です。

これで問題なく動くようになりました!