3

私のコードの中には、どこからともなくバグが発生したように見えるものがあります。追跡したところ、inspect.getmodule実行前と実行後に同じ (同一の) 引数で評価すると、os.chdir異なる結果が得られることがわかりました。

(FWIW、私は OS X で Python 2.7.3 を実行しています。)

この動作は非常に不可解で当惑しているため、バグを修正する最善の方法がわかりません。(言い換えれば、行動の理由を理解した上で、私が考えることができる解決策は、応急処置にすぎません。)

以下のテスト スクリプトは、動作を示しています (もちろん、実際のバグは、はるかに現実的で複雑な状況で発生しています)。

import inspect
import os

def prn(line, mod):
    print ('getmodule called at line %2d; returned module: %-8s (id: %d)' %
           (line - 1, getattr(mod, '__name__', mod), id(mod)))

fr = inspect.currentframe()

mod = inspect.getmodule(fr) # line 10
prn(fr.f_lineno, mod)

mod = inspect.getmodule(fr) # line 13
prn(fr.f_lineno, mod)

os.chdir('subdir')

mod = inspect.getmodule(fr) # line 18
prn(fr.f_lineno, mod)

(注: このコードを実行するには、現在のディレクトリのすぐ下に「subdir」というサブディレクトリが必要です。)

その出力は次のとおりです。

getmodule called at line 10; returned module: __main__ (id: 4297636784)
getmodule called at line 13; returned module: __main__ (id: 4297636784)
getmodule called at line 18; returned module: None     (id: 4296513024)

3 つの呼び出しはすべてgetmodule引数として同じフレーム オブジェクトを持っていますが、最後の呼び出しの結果は、最初の 2 つの呼び出しで生成された結果とは異なることに注意してください。(最初の 2 つの呼び出しの結果は、予想どおり同じです。)

最初の 2 つの呼び出しと 3 番目の呼び出しの唯一の違いは、後者が実行後に行われることos.chdirです。

何が起こっているのかについての洞察をいただければ幸いです。

4

2 に答える 2

0

ここでの問題は、検査しているモジュールがモジュールでもあるということだと思い__main__ます。サンプルコードを別のモジュールに配置し、それをメインモジュールにインポートすると、正常に機能します。フレームを取得した後に作業ディレクトリを変更しているという事実も、何のメリットもありません。

モジュールがアプリケーションでもあることがどうしても必要な場合は、パスを手動で次の場所に渡すことができますinspect.getmodule

import os
import inspect

__filepath__ = os.path.join(os.getcwd(), __file__)

frame = inspect.currentframe()
os.chdir('subdir')
print inspect.getmodule(frame, _filename=__filepath__).__name__

しかし、あなたがしているように作業ディレクトリを変更する必要があることを絶対に確信していますか?私がPythonをコーディングしてきた8年以上の間、実際のコードでPythonを使用したことを覚えていません。

于 2012-08-20T03:21:25.877 に答える
0

Windows 7 X64 の Idle Python 2.7.2 および 2.7.3 でコードを実行しようとしましたが、これを再現できません。私が得るのは: -

getmodule は 12 行目で呼び出されます。返されたモジュール: main (id: 31281464)
getmodule が 15 行目で呼び出されました。返されたモジュール: main (id: 31281464)
getmodule が 20 行目で呼び出されました。返されたモジュール: main (id: 31281464)

しかし、問題は実装だと思います。Python のドキュメントで明らかなように: http://docs.python.org/library/inspect.html#inspect.getmoduleオブジェクトが定義されたモジュールを推測してみてください。

親ディレクトリにいるため、現在のディレクトリを変更する前は、モジュールがmainとして表示されているため、id: 4297636784 が表示されます。 .しかし、現在のディレクトリを変更した後、モジュールは新しいディレクトリから参照できないため、新しいディレクトリからメインモジュールを参照できないため、新しい id: 4296513024 がモジュールとして None で返されます。

于 2012-08-18T20:07:06.180 に答える