Изучение локальных переменных вверх по стеку в Python - PullRequest
0 голосов
/ 29 октября 2019

Я написал небольшую функцию, которая просматривает стек на один уровень и определяет, есть ли в нем переменная. но как мне превратить эту функцию в функцию, которая будет просматривать весь стек до тех пор, пока не найдет локальную переменную для покупки какого-то определенного имени? весь стек, пытаясь найти переменную. Как я могу сделать это с помощью инспекции? Есть ли более простой способ?

Я начал с этого, но f_back не возвращает объект фрейма, поэтому я не знал, куда идти отсюда:

import inspect
def variable_lookup(variable):
previous_frame = inspect.currentframe().f_back
while True:
    print(variable in previous_frame.f_locals.keys())
    previous_frame = inspect.getframeinfo(previous_frame)

Так что кодтерпит неудачу с AttributeError: 'Traceback' object has no attribute 'f_locals'

1 Ответ

1 голос
/ 29 октября 2019

Доступна функция более высокого уровня: inspect.stack(). Это дает вам список FrameInfo() объектов, которые имеют ссылку frame:

for frameinfo in inspect.stack(0):
    if variable in frameinfo.frame.f_locals:
        return frameinfo.frame.f_locals[variable]

Я установил число строк исходного кода (параметр context) на ноль, нет смысла загружатьстроки исходного кода просто для проверки локальных переменных.

Функция stack() в основном реализована следующим образом:

return inspect.getouterframes(inspect.getcurrentframe(), context)

и getouterframes() просто следует ссылкам frame.f_back до тех пор, пока None не станетнашел. Таким образом, вы могли бы также реализовать это с помощью цикла while:

frame = inspect.getcurrentframe()
while frame:
    if variable in frame.f_locals:
        return frame.f_locals[variable]
    frame = frame.f_back

Это, безусловно, более легкий вес, поскольку это позволяет избежать создания FrameInfo() экземпляров для всех кадров в стеке, избегает самоанализа имен файлов для всех кадров. и не требует доступа ко всем связанным фреймам, если переменная найдена раньше.

...