Учитывая объект кадра, я должен получить соответствующий объект модуля. Другими словами, реализуйте 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). Если я мог бы получить функциональные объекты, они имеют __ модуль __ атрибут (и также имейте объекты кода), но это не присутствует в кадре. Действительно, не все объекты кода принадлежат функциональным объектам, таким как код для моего тестового сценария (с утверждают, выше). То же может быть сказано относительно объектов кадра/кода, не имеющих модуль — но многие из них делают, и в моем случае они будут, так, чтобы не должен был быть обработан; однако, простое Ни один или исключение не прекрасны в этом случае, также.
Такое чувство, что я пропускаю что-то простое. Какие потребности быть сделанным, чтобы это работало?
import inspect
def callers_module():
module = inspect.getmodule(inspect.currentframe().f_back)
return module
Хотя 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"]