Как «перепрыгнуть» кадр произвольного python генератора, работающего с экземпляром из pdb / pdbpp? - PullRequest
0 голосов
/ 06 апреля 2020

Предположим, у вас есть этот генератор:

def gen():
  for i in range(10):
    yield i-5

И затем вы делаете это:

try :
  for a in gen():
    print(5 / a) # Obviously, it will crash on a=0
except:
  import pdb; pdb.xpm() # I'm using pdbpp actually

После запуска отладчика (vanilla pdb или pdbpp) есть ли способ «войти» в генератор (go в его фрейм выполнения), чтобы проверить его внутренние переменные, не прерывая программу (я имею в виду просто «наблюдать» и иметь возможность продолжать выполнение, как будто отладчик никогда не запускался) ?

РЕДАКТИРОВАТЬ

Если бы это могло помочь, в реальном коде у меня все еще есть ссылка на генератор, так что это "больше", как это:

g = gen()
try :
  for a in g:
    print(5 / a) # Obviously, it will crash on a=0
except:
  import pdb; pdb.xpm() # I'm using pdbpp actually

1 Ответ

0 голосов
/ 06 апреля 2020

С кодом, который вы опубликовали изначально, вы не можете проверить генератор.

Генератор уже отключен в тот момент, когда вы запускаете отладчик. Единственная ссылка на генератор находилась в стеке значений объекта кадра, где произошло l oop над генератором, и эта ссылка очищается при распространении исключения. Вот программа, демонстрирующая этот факт:

class DelPrintIterator:
    def __iter__(self):
        return self
    def __next__(self):
        return 1
    def __del__(self):
        print('Deleting iterator')

try:
    for i in DelPrintIterator():
        1/0
except ZeroDivisionError:
    print('Too late')

Это печатает

Deleting iterator
Too late

, показывая, что итератор становится недоступным до запуска любого кода в блоке except.


Теперь, с ссылкой на генератор, что-то вроде

g = gen()
try:
    for a in gen():
        print(5 / a)
except ZeroDivisionError:
    ...

тогда ... ну, я не знаю никаких отладчиков, которые позволили бы вам "войти в «кадр стека генератора, когда его нет в стеке, но вы можете вручную извлечь кадр с помощью g.gi_frame, а затем начать просматривать те же атрибуты, которые использует отладчик, например frame.f_locals или frame.f_lineno. (Атрибуты объекта Frame перечислены в документации модуля inspect.) Это будет менее удобно, чем интерфейс отладчика, но та же информация все еще там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...