ipython インタラクティブ シェル内にいるときに、スクリプトから関数を動的にロードしようとしています。たとえば、次のような python スクリプトがあるとします。
# script.py
import IPython as ip
def Reload():
execfile('routines.py', {}, globals())
if __name__ == "__main__":
ip.embed()
ファイル routines.py が次のようになっているとします。
# routines.py
def f():
print 'help me please.'
def g():
f()
ここでスクリプト script.py を実行すると、インタラクティブ シェルに入ります。次のように入力すると、g() への呼び出しが機能します。
execfile('routines.py')
g()
ただし、次のように入力すると、g() の呼び出しは失敗します。
Reload()
g()
「グローバル名 f が定義されていません」というエラー メッセージが表示されます。ただし、対話型シェルで globals() と入力すると、出力に f と g が含まれていることがわかります。
これら2つの違いは何ですか?
アップデート:
以下は機能しますが、推奨される解決策ではないため、上記の問題に対するより良い解決策が必要です。
script.py を次のように変更すると:
# script.py
import IPython as ip
def Reload():
execfile('routines.py')
if __name__ == "__main__":
ip.embed()
routines.py を次のように変更します。
# routines.py
global f
global g
def f():
print 'help me please.'
def g():
f()
次に、対話型シェルで Reload() を呼び出してから g() を呼び出すと、機能します。ただし、グローバル名を宣言する必要があるため、これは推奨される方法ではありません。
更新 2:
問題は ipython とは無関係のようです。routines.py の最初のバージョンで Python シェルを起動し、次のように手動で入力します。
def Reload():
execfile('routines.py', {}, globals())
g()
g() の呼び出しも失敗します。しかし、次の作品:
execfile('routines.py')
g()