1

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()
4

1 に答える 1