1

brian2ニューラル ネットワークのシミュレーションを実行するために使用しています。各シミュレーション中にデータを記録するために、brian2SpikeMonitorクラスのインスタンスをいくつか作成しています。これらのモニターを、dict 内包表記を使用して作成された dict に格納したいと考えています。

テストとして、インタラクティブ セッションで以下を実行します。

In [1]: import brian2

In [2]: pe_mt = brian2.PoissonGroup(1, 100 * brian2.Hz)

In [3]: record_pops = ['pe_mt']

In [4]: {'mon_' + pop: brian2.SpikeMonitor(eval(pop)) for pop in record_pops}
Out[4]: {'mon_pe_mt': <SpikeMonitor, recording spikemonitor>}

すべてが素晴らしく見えます。しかし、このコードを次の関数に移動すると

def test_record():
    pe_mt = brian2.PoissonGroup(1, 100 * brian2.Hz)
    record_pops = ['pe_mt']
    return {'mon_' + pop: brian2.SpikeMonitor(eval(pop)) for pop in
            record_pops}

それを呼び出すと、次のエラーが表示されます

In [9]: tests.test_record()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-9-4d3d585b2c97> in <module>()
----> 1 tests.test_record()

/home/daniel/Science/dopa_net/brian/ardid/tests.py in test_record()
     61     record_pops = ['pe_mt']
     62     return {'mon_' + pop: brian2.SpikeMonitor(eval(pop)) for pop in
---> 63                 record_pops}
     64     # DEBUG ###################
     65     #monitors = utils.record(['pe_mt'], 'spikes', None, None, pe_mt, None, None)

/home/daniel/Science/dopa_net/brian/ardid/tests.py in <dictcomp>((pop,))
     60     # DEBUG ###################
     61     record_pops = ['pe_mt']
---> 62     return {'mon_' + pop: brian2.SpikeMonitor(eval(pop)) for pop in
     63                 record_pops}
     64     # DEBUG ###################

/home/daniel/Science/dopa_net/brian/ardid/tests.py in <module>()

NameError: name 'pe_mt' is not defined

何が起きてる?「pe_mt」関数内で定義されています。

次のように、辞書内包表記をリスト内包表記に変更すると、

return [brian2.SpikeMonitor(eval(pop)) for pop in record_pops]

エラーは発生しません。SpikeMonitor適切に定義されたオブジェクトのリストを取得します。

locals()[pop]現在消去されている回答は、代わりに使用することを示唆していますeval(pop)。これにより、同等のエラーが発生することに注意してください。

In [20]: tests.test_record()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-20-4d3d585b2c97> in <module>()
----> 1 tests.test_record()

/home/daniel/Science/dopa_net/brian/ardid/tests.py in test_record()
     61     record_pops = ['pe_mt']
     62     return {'mon_' + pop: brian2.SpikeMonitor(locals()[pop]) for pop in
---> 63                 record_pops}
     64     # DEBUG ###################
     65     #monitors = utils.record(['pe_mt'], 'spikes', None, None, pe_mt, None, None)

/home/daniel/Science/dopa_net/brian/ardid/tests.py in <dictcomp>((pop,))
     60     # DEBUG ###################
     61     record_pops = ['pe_mt']
---> 62     return {'mon_' + pop: brian2.SpikeMonitor(locals()[pop]) for pop in
     63                 record_pops}
     64     # DEBUG ###################

KeyError: 'pe_mt'
4

2 に答える 2

0

1: 忘れてくださいeval。渡された文字列が識別子ではなく式または関数呼び出しである場合、予期しないことが発生する可能性があるためです。名前でローカル変数を取得する必要がある場合は、 を使用してきれいに行うことができますlocals()[name]

ドキュメント:locals


2: すべての内包表記とジェネレーター式 (python 2.x のリスト内包表記を除く)には独自の名前空間があるためlocals()、内包表記の内部では、変数を持たないものを参照します。デフォルトでローカル変数evalをキャプチャする場合も同様です。

locals ディクショナリを省略すると、デフォルトで globals ディクショナリになります。両方の辞書が省略されている場合、式は eval() が呼び出された環境で実行されます。

早めに取得することで回避できます。

def test_record():
    pe_mt = brian2.PoissonGroup(1, 100 * brian2.Hz)
    record_pops = ['pe_mt']
    groups = locals()    
    return {'mon_' + pop: brian2.SpikeMonitor(eval(pop, globals(), groups)) for pop in record_pops}
    # or better
    return {'mon_' + pop: brian2.SpikeMonitor(groups[pop]) for pop in record_pops}

またはより慣習的に、なしでlocals

def test_record():
    groups = {
        "pe_mt": brian2.PoissonGroup(1, 100 * brian2.Hz),
    }
    return {'mon_' + key: brian2.SpikeMonitor(value) for key, value in groups.iteritems()}
于 2015-04-09T19:50:22.703 に答える