Доступ к местным жителям, доступным в предыдущем кадре стека

1

У меня есть диспетчер контекста отладки, в котором я хотел бы получить доступ к locals() во время инициализации менеджера контекста, не указывая локальные параметры в качестве аргумента. Это возможно?

Я хотел бы сделать это в общем случае, чтобы мой менеджер контекста Debug можно было использовать из любого файла, импортирующего Debug, а не только из примера tinkertoy ниже.

Вот мой минимальный пример:

import inspect

class Debug:
    def __init__(self):

        frames = inspect.stack()

        for frame in frames:
            line = frame.code_context[0]
            if "Debug" in line:
                break

        # I want to get the locals() at the time debug was called here!
        # give me i_will_be_in_the_locals
        raise Exception()

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass


if __name__ == "__main__":

    i_will_be_in_the_locals = 42
    with Debug():
        "hi"
  • 0
    Что не так с тем, что вы уже пробовали? Выше полного кода?
  • 0
    Я хотел бы получить доступ к locals (), где вызывался Debug (), где сейчас генерируется исключение. Я уверен, что для этого нужно как-то использовать насекомое, но я так и не смог понять, как это сделать.
Теги:
contextmanager

1 ответ

0

Объект frame находится внутри определенной вами переменной frame. Чтобы получить локальные переменные для объекта фрейма, вы можете вызвать его атрибут f_locals следующим образом:

import inspect

class Debug:
    def __init__(self):

        frames = inspect.stack()

        for frame in frames:
            line = frame.code_context[0]
            if "Debug" in line:
                break

        # I want to get the locals() at the time debug was called here!
        # give me i_will_be_in_the_locals
        from pprint import pprint
        pprint(frame.frame.f_locals)

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass


if __name__ == "__main__":

    i_will_be_in_the_locals = 42
    with Debug():
        "hi"

Возвращаемое значение:

{'Debug': <class '__main__.Debug'>,
 '__builtins__': <module 'builtins' (built-in)>,
 '__cached__': None,
 '__doc__': None,
 '__file__': '/home/user1/main-projects/overflow/file.py',
 '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7bbb44f7f0>,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 'i_will_be_in_the_locals': 42,
 'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>}
  • 0
    Замечательный. Посмотрите на это и посмотрите, работает ли это в общем случае, а затем примите :)
  • 0
    Благодарю. Я вчера попробовал f_locals , но, должно быть, путал себя с двойным frame ( frame.frame ). Я, вероятно, сделал frame.f_locals XD.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню