10

フレーム オブジェクトを指定すると、対応するモジュール オブジェクトを取得する必要があります。つまり、これが機能するように callers_module を実装します。

import sys
from some_other_module import callers_module
assert sys.modules[__name__] is callers_module()

(このテスト ケースの関数でスタック トレースを生成できるため、これは同等です。インポートは、その例を完全でテスト可能にするためだけにあり、callers_module が別のモジュールにあるため、__name__ を使用するショートカットを使用するのを防ぎます。 .)

私はこれを試みました:

import inspect
def callers_module():
  return inspect.currentframe().f_back

フレームオブジェクトを取得し、その上でf_codeがコードオブジェクトを提供しますが、対応するモジュールまたはその名前を取得する方法がわかりません(sys.modulesで使用するため)。関数オブジェクトを取得できた場合、それらには __module__ 属性があります (コード オブジェクトもあります) が、フレームには存在しません。実際、すべてのコード オブジェクトが関数オブジェクトに属しているわけではありません。たとえば、私のテスト ケースのコード (上記の assert を使用) などです。モジュールを持たないフレーム/コード オブジェクトについても同じことが言えます。ただし、その場合も単純な None または例外で問題ありません。

シンプルなものが欠けているような気がします。これが機能するために何をする必要がありますか?

4

2 に答える 2

12

inspect.getmoduleはうまく機能し、実際にそれを見つけるために間違った場所を探していましたが、私にとっては少し良い解決策を見つけました:

def callers_module():
  module_name = inspect.currentframe().f_back.f_globals["__name__"]
  return sys.modules[module_name]

それでもinspect.currentframe(まったく同じsys._getframeよりも優先されます)を使用しますが、inspectのモジュール-ファイル名マッピング(inspect.getmodule内)を呼び出しません。

さらに、この質問は__all__を管理するための興味深い方法に影響を与えました:

from export import export

@export
class Example: pass

@export
def example: pass

answer = 42
export.name("answer")

assert __all__ == ["Example", "example", "answer"]
于 2010-01-06T05:44:56.867 に答える
5
import inspect
def callers_module():
   module = inspect.getmodule(inspect.currentframe().f_back)
   return module
于 2010-01-04T17:50:39.380 に答える