Как обновить вложенные функции в ipdb? - PullRequest
0 голосов
/ 11 января 2019

Я запускаю IPython3 в Emacs с Elpy и пытаюсь редактировать вложенные функции на лету. Например, у меня есть прикрепленный файл, открытый в одном кадре, и IPython3 в другом. Я отправляю буфер на IPython с C-c C-y b, переключаюсь на фрейм IPython с C-x o.

import sys

def print_name():
    print ("Alice")

def name ():
    print_name()

def main(argv):
    print ("In main.")
    import ipdb; ipdb.set_trace()
    name()

if __name__ == "__main__":
    main(sys.argv[1:])

Теперь я запускаю код, набрав main(0).

In [1]: main(0)
In main.
> /Users/ayank/Documents/programming/python/bar.py(12)main()
     11     import ipdb; ipdb.set_trace()
---> 12     name()
     13 

Я получаю приглашение отладки и выполняю:

ipdb> name()
Alice

Теперь я возвращаюсь к окну кода для print_name(), меняю Alice на Bob и повторно отправляю функцию на IPython3 с помощью C-c C-y f. Я вижу следующее, что появляется в кадре IPython:

ipdb> def print_name():
 ...:     print ("Bob")

Я возвращаюсь к фрейму IPython и набираю:

ipdb> name()
Alice
ipdb> print_name()
Bob

Это не правильно: оба должны печатать Bob. Я могу переслать весь буфер в IPython с C-c C-y b, но я получаю один и тот же ответ: name() всегда выводит Alice.

Что здесь происходит? Как обновить вложенные функции в IPython3 при отладке?

1 Ответ

0 голосов
/ 14 января 2019

Проблема заключается в том, что когда выполнение достигает точки останова, код, введенный в приглашении ipdb, выполняется в пространстве имен main. Следовательно, новый print_name() находится в пространстве имен main, в то время как name() продолжает вызывать print_name() в пространстве имен global.

Новый print_name() можно добавить в пространство имен global вручную, набрав globals()['print_name'] = print_name.

Пример выполнения кода:

ayank@snorri$ ./foo.py
In main.
> /Users/ayank/Documents/programming/python/bar.py(13)main()
     12     import ipdb; ipdb.set_trace()
---> 13     name()
     14 
ipdb> print_name()
Alice
ipdb> name()
Alice
ipdb> def print_name(): print ("Bob")
ipdb> print_name()
Bob
ipdb> name()
Alice
ipdb> globals()["print_name"] = print_name
ipdb> name()
Bob
...