2017-08-08 7 views
0

私はSHA2017バッジに手を差しています。私は、以下のプログラムを書き、シミュレータでそれを実行しました:これはMicroPythonのバグですか?

import ugfx 
import badge 

def key_pressed(key, is_pressed): 
    print('key_pressed(key=%r, is_pressed=%r)' % (key, is_pressed)) 

badge.init() 
ugfx.init() 
ugfx.input_init() 
for key in [ugfx.JOY_LEFT, ugfx.JOY_UP, ugfx.JOY_RIGHT, ugfx.JOY_DOWN]: 
    ugfx.input_attach(key, (lambda is_pressed: key_pressed(key, is_pressed))) 
# Uncommenting this makes all keystrokes get interpreted as JOY_UP: 
# ugfx.input_attach(key, (lambda is_pressed: key_pressed(key, is_pressed))) 
# But uncommenting this makes JOY_UP work as intended and doesn't affect other keys 
# ugfx.input_attach(ugfx.JOY_UP, (lambda is_pressed: key_pressed(ugfx.JOY_UP, is_pressed))) 
while True: 
    pass 

私はこれを実行すると、任意のキーを押すと、私はJOY_DOWNを押したと言うだろう。最初の行のコメントを外すと、JOY_UPを押して、最後のコメント行のコメントを外すだけで、意図したとおりに動作するJOY_UPを除いて、すべてのキーがJOY_DOWNになります。

これはバグか意図した動作ですか? MicroPythonがラムダをコンパイルするのは一度だけで、 "key"への参照が結びついているようです。

+0

コメント行は同一であるように見えます。 – user2357112

+0

@ user2357112あなたは正しいです、私はそれを変更しました – d33tah

+0

他の多くの言語とは異なり、Pythonの 'lambda'はクロージャを構成しません。それは依然として外部変数を参照し、ローカルコピーは参照しません。 – 9000

答えて

1

問題は、変数keyが更新されていることであり、したがって式は、同様ラムダ内のすべての参照、更新されています

はあなたにもスコープkeyする必要があります。

for key in [ugfx.JOY_LEFT, ugfx.JOY_UP, ugfx.JOY_RIGHT, ugfx.JOY_DOWN]: 
    ugfx.input_attach(key,lambda k: (lambda is_pressed: key_pressed(k, is_pressed)(key)))

それとも、使用することができます:

from functools import partial 

for key in [ugfx.JOY_LEFT, ugfx.JOY_UP, ugfx.JOY_RIGHT, ugfx.JOY_DOWN]: 
    ugfx.input_attach(key,partial(lambda k, is_pressed: key_pressed(k, is_pressed),key))

+0

これはとても醜いです!ありがとう:D – d33tah

+0

@ d33tah:私はそれに同意します。ラムダ式などを返す関数を定義することもできますが、まだそれほどエレガントではありません。 –

+0

'functools.partial'がより明確になります。 – user2357112

関連する問題