Получите объект модуля от стекового фрейма

Учитывая объект кадра, я должен получить соответствующий объект модуля. Другими словами, реализуйте callers_module, таким образом, это работает:

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

(Который был бы эквивалентен, потому что я могу генерировать отслеживание стека в функции для этого тестового сценария. Импорт должен там просто сделать тот пример завершенным и тестируемым, и препятствовать тому, чтобы callers_module брал ярлык использования __ имя __, так как это находится в другом модуле.)

Я делал попытку этого:

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

Который получает объект кадра, на котором f_code даст мне объект кода, но я не могу узнать, как получить соответствующий модуль или его имя (для использования с sys.modules). Если я мог бы получить функциональные объекты, они имеют __ модуль __ атрибут (и также имейте объекты кода), но это не присутствует в кадре. Действительно, не все объекты кода принадлежат функциональным объектам, таким как код для моего тестового сценария (с утверждают, выше). То же может быть сказано относительно объектов кадра/кода, не имеющих модуль — но многие из них делают, и в моем случае они будут, так, чтобы не должен был быть обработан; однако, простое Ни один или исключение не прекрасны в этом случае, также.

Такое чувство, что я пропускаю что-то простое. Какие потребности быть сделанным, чтобы это работало?

9
задан 4 January 2010 в 17:27
поделиться

2 ответа

import inspect
def callers_module():
   module = inspect.getmodule(inspect.currentframe().f_back)
   return module
3
ответ дан 4 December 2019 в 21:10
поделиться

Хотя 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).

Вдобавок этот вопрос вдохновил на интересный способ управлять __все __ :

from export import export

@export
class Example: pass

@export
def example: pass

answer = 42
export.name("answer")

assert __all__ == ["Example", "example", "answer"]
7
ответ дан 4 December 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: