2009-10-04 3 views
26

これは非常に基本的な質問ですが、私はオンラインで検索して回答を見つけることができませんでした。python refresh/reload

私はArcGISを制御するためにPythonを使用しています。私は、あらかじめ記述されたコードを呼び出す単純なPythonスクリプトを持っています。

ただし、あらかじめ書かれたコードを変更すると、変更には反映されません。私はこのモジュールをインポートし、それをリフレッシュしようとしましたが、何も起こりません。

私はファイルを別の場所に移動しても、スクリプトは正常に動作します。私が昨日したことの1つは、すべてのPythonファイルがsysパス(sys.append( 'path')を使って)にあるフォルダを追加したことです。

ありがとうございました。不適切な用語をおかけして申し訳ありません。

答えて

31

execfile機能(またはexec()eval()compile())を使用することができますそれはあなたが「リフレッシュ」で何を意味するかは不明だが、Pythonの通常の行動は、あなたがそれのためのソフトウェアを再起動する必要があるということですPythonモジュールを新たに見て、それを再度読んでください。

変更をしても、再起動後の世話をされていない場合、これは2つのエラーの1によるものです:

  1. PYCファイルのタイムスタンプが間違っているし、将来のある時点。
  2. 実際に間違ったファイルを編集しています。

reload()コマンドを使用してソフトウェアを再起動しなくても、ファイルを再読み込みすることができます。モジュール内の何かを指す変数は、リロード後に再インポートする必要があることに注意してください。このような何か:

import themodule 
from themodule import AClass 

reload(themodule) 
from themodule import AClass 
+0

私は同様の問題を抱えていました。私は、最初の 'from mododule import AClass'を取り除くことはやっていることに気付きました。両方の理由がありますか? – pentandrous

+0

問題を解決するのは本当に "トリック"ではなく、実際の問題は他のどこかから来ています。代わりにそれを解決しようとする必要があります。 –

19

これを行う1つの方法は、reloadを呼び出すことです。

例:ここではfoo.pyの内容は次のとおりです。

インタラクティブセッションで
def bar(): 
    return 1 

、私が行うことができます。

>>> import foo 
>>> foo.bar() 
1 

その後別のウィンドウでは、私はfoo.pyを変更することができます。

def bar(): 
    return "Hello" 

戻る対話セッションでは、foo.bar()私がするまで、1ターン:

>>> reload(foo) 
<module 'foo' from 'foo.py'> 
>>> foo.bar() 
'Hello' 

reloadを呼び出すと、あなたのモジュールは、ディスク上のファイルが変更された場合でも、最新であることを確実にする1つのの方法です。必ずしも最も効率的ではありません(reloadの前にファイルの最後の変更時刻を確認するか、pyinotifyのようなものを使用する方が良いかもしれません)。

モジュールが読み込まれるたびにPythonがソースモジュールから読み込まない理由の1つは(比較的)高価なことです.300kbのモジュールを使用していて、ファイルからただ1つの定数を使用していたらどうなりますか? Pythonはモジュールを一度ロードし、reloadまでそれをメモリに保持します。

1

私は本当にあなたが意味するものではないので、私を修正することを躊躇しないでください。モジュールをインポートしています - あなたのプログラムでmymodule.pyと呼んでいますが、内容を変更すると違いは見えませんか?

Pythonは、使用されるたびにmymodule.pyの変更を探しません。最初に読み込み、バイトコードにコンパイルして内部的に保持します。通常、コンパイルされたバイトコード(mymodule.pyc)も保存されます。次にプログラムを起動すると、mymodule.pyがmymodule.pycより新しいかどうかがチェックされ、必要に応じて再コンパイルされます。

あなたがする必要がある場合は、明示的にモジュールをリロードすることができます:もちろん

import mymodule 

[... some code ...] 

if userAskedForRefresh: 
    reload(mymodule) 

を、それはそれよりも複雑であり、あなたは、あなたが他のについてあなたのプログラムで何をすべきかに応じて、副作用を有することができます例えば、変数がmymoduleで定義されたクラスに依存する場合

また、あなたが

+0

は、あなたの答えありがとうございました。私はリロードを使用して、プログラムを閉じる/再オープンしようとしました。 問題は、元のコードで同じ名前のファイルが原因であることが判明しました。私は新しい場所からそれをインポートしていると思っていましたが、それはまだ古いファイルを使用していました。 – womble

3

モジュール内のすべてのオブジェクトをインポートするときに、私はweb2pyのが私の現在のコードを使用していたことを確認するために、次を使用:

import buttons 
import table 
reload(buttons) 
reload(table) 
from buttons import * 
from table import * 
0

私はジオプロセシングスクリプトを作成する正確に同じ問題がありましたArcGIS 10.2私はPythonツールボックススクリプト、ツールスクリプト、そして共通スクリプトを持っていました。私は実行されたコードのバージョンを制御するツールのDev/Test/Prodのパラメータを持っています。 Devはdevフォルダ内のコードをテストフォルダからテストし、prodフォルダからプロットします。ツールがArcCatalogから実行されている場合、共通の開発者スクリプトの変更は実行されません。 ArcCatalogを閉じると違いはありません。 DevまたはTestを選択したとしても、常にprodフォルダから実行されます。

リロード(myCommonModule)をツールスクリプトに追加すると、この問題は解決されました。

3

IPythonシェルで実行している場合、存在するいくつかのマジックコマンドがあります。

IPythonのドキュメントでは、autoreload extensionと呼ばれるこの機能をカバーしています。

元々、私はJonathan March's blog posting on this very subject(このリンクのポイント3を参照)からこの解決策を見つけました。

基本的にあなたがしなければならないすべては次の通りである、とあなたが保存した後、あなたが行った変更が自動的に反映されます。

In [1]: %load_ext autoreload 

In [2]: %autoreload 2 

In [3]: Import MODULE 

In [4]: my_class = Module.class() 
     my_class.printham() 
Out[4]: ham 

In [5]: #make changes to printham and save 
In [6]: my_class.printham() 
Out[6]: hamlet