Praca z klątwami w IPythonie. Jak mogę to poprawić?
Znalazłem sposób na interaktywną pracę z przekleństwami, jednocześnie ciesząc się większością zalet IPythona. Działa z pewnymi ograniczeniami, ale nie tak dobrze, jak bym chciał.
Oryginalnym problemem jest oczywiście to, że chciałbym móc pracować z moją interaktywną sesją Pythona, jednocześnie kontrolując ekran terminalu, używając modułu curses (ncurses) (luburwid, na przykład). Jednym z rozwiązań jest napisanie prostego serwera TCP z prostą pętlą zdarzeń, która ocenia każdy ciąg odczytywany z gniazda i wysyła z powrotem serializowane ciągi reprezentujące i zwracające wyniki. Jak opisano tutaj:SO: Czy istnieje sposób interaktywnego programowania aplikacji Python curses).
Oto nieco prostsza sztuczka (zakładając, że masz zainstalowany IPython).
#!/usr/bin/python
#!/usr/bin/env python
from IPython import embed_kernel
import curses
def interact_with_curses(screen):
'''set global stdscr variable and run embedded IPython kernel
suitable to be called by curses.wrapper()
'''
global stdscr
stdscr = screen
embed_kernel()
if __name__ == '__main__':
curses.wrapper(interact_with_curses)
(lekko zmieciony, aby podświetlić składnię SO).
Uruchomienie tego spowoduje, że dane wyjściowe będą wyglądać mniej więcej tak:
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2869.json
I przełączając się na inne okno lub sesję ekranu możesz uruchomić:
ipython console --existing kernel-2869.json
Aby połączyć się z tym procesem i pracować z nim.
To jest wystarczająco miłe. Możesz wtedy wywoływać takie rzeczystdscr.refresh()
. Pracuj z obiektami curses / window i pad, zadzwońdir()
aby zbadali ich funkcjonalność i ogólnie pracowali z kodem tak, jakbyś był w normalnej sesji IPython, która po prostu aktualizuje ekran innego terminala i czyta z niego również (poprzez funkcje wprowadzania curses).
Problemy z tym podejściem i pytania:
Aby wyjść, wydaje mi się, że muszę uruchomić quit () z konsoli IPython, a to nie powoduje wyjścia interpretera w normalny sposób. Wydaje się, że nie pozwalacurses.wrapper()
zresetować terminal i różne próby wywołania.endwin()
, .resetty()
(po wykonaniu a.savetty()
oczywiście),.reset_shell_mode()
(i.reset_prog_mode()
) i tak dalej wszystko zawiodło. Próbowałem dzwonić do nich po wywołaniucurses.wrapper()
i próbowałem je zarejestrować za pomocąatexit
Jak mogę wyjść z takiej sesji?Ukończenie [Tab] nie działaJak sprawić, aby [Tab] IPythona całkowicie działał przez sesję konsoli IPython na jednym z tych osadzonych jąder?Wywołanie IPythonaembed_kernel()
Funkcja wypisuje informacje o gnieździe na ekranie curses, który jest już zainicjowany przezcurses.wrapper()
w tamtym czasie, w tamtym momencie. To jest brzydkie; także jeśli chcesz zrobić bardziej interesującą pracę, w przekleństwach i przed wywołaniemembed_kernel()
funkcja wtedy nie widzę tekstu, który został wydrukowany na stdout lub stderr przez tę funkcję.Jak zrobićembed_kernel()
cicho i zmusić go do zarejestrowania szczegółów połączenia za pomocą innego mechanizmu? Czy mogę podać własną nazwę gniazda / ścieżkę do użycia?Jestem pewien, że zastanowię się nad innymi pytaniami, ale mam nadzieję, że inni uznają ten trik za przydatny i odkryją kilka innych sztuczek, których mogę użyć, gdy chcę się zająć kodowaniem Pythona.