3

さらに処理するために、情報をユーザー定義関数にロードしようとしています。入力ファイルはプログラマー以外が生成する必要があるため、次の形式を選択しました。

#contents of vessel_data.txt
hull_length = 100000.
hull_width  = 50000.
etc.

私の関数は、入力ファイルを介してロードしますexecfile()。次に、データを配列にグループ化し、それを関数の出力として渡します。おおよそ次のようになります。

file_path = ..\vessel_name.txt

def my_input_func(file_path):
    execfile(file_path)

    data = np.array([[hull_length],
                     [hull_width ],
                     [etc.       ]])

    return(data)

exec()と を介してデータをロードすることexecfile()が嫌われていることは知っていますが、入力はプログラマー以外によって生成されることに注意してください。とにかく、次のエラーが表示されます。

NameError: global name 'hull_length' is not defined

localこれらの行を追加した後、変数が期待どおりに名前空間に読み込まれていることを確認できます。

print 'Locals:  ' + str([x for x in locals()  if x[0] == 'h'])
print 'Globals: ' + str([x for x in globals() if x[0] == 'h'])

私を困惑させているのはglobal、変数を定義しようとするときに関数が名前空間を参照する理由です。特に明記しない限り、関数内のすべてが関数にローカルな名前空間を扱っているという印象を受けました。execfile()コマンドを次のように変更することで、機能させることができます。

execfile(file_path, globals())

しかし、すべてをグローバル名前空間にロードすることに興味はありません。

globalでは、名前空間にすべてをロードせずにこれを機能させるにはどうすればよいでしょうか?

よろしく、ラスムス

======== 編集 =======

これは、クエンティンの答えに基づいて機能させる方法です。

file_path = ..\vessel_name.txt

def my_input_func(file_path):
    vessel_vars = {}
    execfile(file_path, vessel_vars)

    data = np.array([[vessel_vars['hull_length']],
                     [vessel_vars['hull_width'] ],
                     [vessel_vars['etc.']       ]])

    return(data)

乾杯クエンティン!

4

1 に答える 1

4

execfile()のドキュメントは、関数のローカル変数を変更したいことについて警告しています: それは不可能です!

デフォルトのローカルは、以下の関数 locals() で説明されているように機能します。デフォルトのローカル ディクショナリへの変更は試行しないでください。関数 execfile() が戻った後、ローカルに対するコードの影響を確認する必要がある場合は、明示的なローカル ディクショナリを渡します。 関数のローカルを変更するために execfile() を確実に使用することはできません。

execfile() についてではなく、locals() についてです。

def f():
   locals()['a'] = 3
   print(a)

も得られNameError: global name 'a' is not definedます。これはおそらく最適化のためです。ここでの解決策は、辞書を使用することです。

file_path = os.path.join('..', 'vessel_name.txt')

def my_input_func(file_path):
    vessel = {}
    execfile(file_path, vessel)

    data = np.array([[vessel['hull_length']],
                     [vessel['hull_width'],
                     [vessel['etc.']])

    return(data)

注: Python 2 を使用していると仮定していますが、Python 3 でも同じですが、execfile() が exec() になり、自分でファイルを開く必要がある点が異なります。

于 2013-09-05T08:40:36.003 に答える