Piszę trochę Pythona IDE i chcę dodać proste debugowanie. Nie potrzebuję wszystkich funkcji Winpdb. Jak uruchomić program Pythona (według nazwy pliku) z punktem przerwania ustawionym na numerze wiersza, aby działał do tego numeru linii i zatrzymywał się? Zauważ, że nie chcę tego robić z wiersza poleceń i nie chcę edytować źródła (wstawiając np. Set_trace). I nie chcę, żeby zatrzymywał się w pierwszej linii, więc muszę uruchomić debugger. Próbowałem wszystkich oczywistych sposobów z pdb i bdb, ale muszę czegoś brakuje.Uruchamianie sesji debugowania Pythona z poziomu programu, a nie z konsoli
Odpowiedz
Prawie jedyny możliwy sposób na zrobienie tego (o ile wiem) to uruchomienie Pythona jako podprocesu z twojego IDE. Pozwala to uniknąć "zanieczyszczenia" z aktualnego interpretera Pythona, co sprawia, że dość prawdopodobne jest, że program będzie działał w taki sam sposób, jak gdyby był uruchamiany niezależnie. (Jeśli masz problemy z tym, należy sprawdzić subprocess środowiska). W ten sposób można uruchomić skrypt w „tryb debugowania” używając
p = subprocess.Popen(args=[sys.executable, '-m', 'pdb', 'scriptname.py', 'arg1'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Pozwoli to uruchomić Pythona w wierszu debugera. trzeba uruchomić niektórych poleceń debugera ustawić punkty przerwania, które można zrobić tak:
o,e = p.communicate('break scriptname.py:lineno')
Jeśli to działa, o
powinno być normalne wyjście interpretera Pythona po ustawia punkt przerwania, a e
powinien być pustym. Sugeruję, abyś się tym zajmował i dodał kilka sprawdzeń w swoim kodzie, aby upewnić się, czy punkty przerwania zostały poprawnie ustawione.
Po tym, można uruchomić program działa z
p.communicate('continue')
W tym momencie, że prawdopodobnie chcesz zaczepić wejścia, wyjścia i strumieni błędzie do konsoli, że jesteś wtłaczania w swoje IDE. Prawdopodobnie będzie trzeba to zrobić za pomocą pętli zdarzeń, z grubsza tak:
while p.returncode is None:
o,e = p.communicate(console.read())
console.write(o)
console.write(e)
Należy uznać, że fragment skutecznie być pseudokod, gdyż w zależności od tego, jak dokładnie Twoje prace konsoli, będzie to prawdopodobnie zajmie trochę do majsterkowania Zrób to dobrze.
Jeśli wydaje się zbyt brudny, prawdopodobnie można uprościć proces nieco korzystania z funkcji pdb
i bdb
modułów Pythona (zgaduję „python debugger”, a podstawową debuger”odpowiednio). Najlepszym odniesienia, jak to zrobić jest to kod źródłowy samego modułu pdb
. Zasadniczo sposób podziału modułów jest taki, że bdb
obsługuje funkcje debugowania "pod maską", takie jak ustawianie punktów przerwania lub zatrzymywanie i restartowanie wykonywania; który obsługuje interakcje użytkownika, tj. odczytywanie poleceń i wyświetlanie danych wyjściowych:
Dla zintegrowanego z IDE debuggera warto t zachowanie modułu pdb
na dwa sposoby, że mogę myśleć:
- mieć to automatycznie ustawić punkty przerwania podczas inicjalizacji, bez konieczności jawnie wysłać tekstowych poleceń zrobić
- zrobić to wziąć wejście od i wysłać dane wyjściowe do konsoli IDE za
Tylko te dwie zmiany powinny być łatwe do wdrożenia przez instacji pdb.Pdb
.Można utworzyć podklasę którego inicjator pobiera listę przerwań jako dodatkowy argument:
class MyPDB(pdb.Pdb):
def __init__(self, breakpoints, completekey='tab',
stdin=None, stdout=None, skip=None):
pdb.Pdb.__init__(self, completekey, stdin, stdout, skip)
self._breakpoints = breakpoints
Logicznym miejscem faktycznie ustawić punkty przerwania tylko po debugger czyta swój plik .pdbrc
, która występuje w metodzie pdb.Pdb.setup
. W celu przeprowadzenia rzeczywistego ustawienia, należy zastosować metodę set_break
odziedziczone z bdb.Bdb
:
def setInitialBreakpoints(self):
_breakpoints = self._breakpoints
self._breakpoints = None # to avoid setting breaks twice
for bp in _breakpoints:
self.set_break(filename=bp.filename, line=bp.line,
temporary=bp.temporary, conditional=bp.conditional,
funcname=bp.funcname)
def setup(self, f, t):
pdb.Pdb.setup(self, f, t)
self.setInitialBreakpoints()
Ten fragment kodu, który działa dla każdego zakresu wartości są przekazywane jako np nazwana krotka. Można również eksperymentować z bezpośrednim budowaniem instancji bdb.Breakpoint
, ale nie jestem pewien, czy to działałoby poprawnie, ponieważ bdb.Bdb
zachowuje własne informacje o punktach przerwania.
Następnie należy utworzyć nową metodę main
dla swojego modułu, która uruchamia ten sam sposób uruchamiania pdb
. Do pewnego stopnia możesz skopiować metodę main
z pdb
(i oczywiście oświadczenie if __name__ == '__main__'
), ale będziesz musiał uzupełnić ją w jakiś sposób, aby przekazać informacje o twoich dodatkowych punktach przerwania. Co sugeruję pisze punkty przerwania do pliku tymczasowego z Twojego IDE i przepuszczenie nazwę tego pliku jako drugi argument:
tmpfilename = ...
# write breakpoint info
p = subprocess.Popen(args=[sys.executable, '-m', 'mypdb', tmpfilename, ...], ...)
# delete the temporary file
Następnie w mypdb.main()
, należy dodać coś takiego:
def main():
# code excerpted from pdb.main()
...
del sys.argv[0]
# add this
bpfilename = sys.argv[0]
with open(bpfilename) as f:
# read breakpoint info
breakpoints = ...
del sys.argv[0]
# back to excerpt from pdb.main()
sys.path[0] = os.path.dirname(mainpyfile)
pdb = Pdb(breakpoints) # modified
Teraz możesz użyć nowego modułu debuggera, tak jak byś użył pdb
, z tym że nie musisz jawnie wysyłać poleceń break
przed rozpoczęciem procesu. Ma to tę zaletę, że można bezpośrednio podłączyć standardowe wejście i wyjście podprocesu Python do konsoli, jeśli pozwala to na to.
Dzięki za wejście. Ale otrzymuję ValueError: operacja I/O na zamkniętym pliku, jak tylko dotrze do p.communicate ("kontynuuj"). Używanie close_fds = Fałsz w Popen nie pomaga ... –
@antwin: pamiętaj, że to wszystko jest w istocie pseudokodą. Jeśli po prostu uruchomisz go tak, jak jest, dostaniesz wszelkiego rodzaju błędy. Musisz dostosować go do własnego projektu w sposób, o którym nie mogłem powiedzieć nic, bez dostępu do twojego kodu źródłowego. –
Rzeczywiście! Więc wyodrębniłem twoją sugestię do następującego pliku #!/Usr/bin/python import sys, subprocess fileName = '/tmp/test.py' lineno = 4 p = podproces.Popen (args = [sys.executable , '-m', 'pdb', fileName], stdin = podproces.PIPE, stdout = podproces.PIPE, stderr = podproces.STDOUT) cmd = 'przerwa% s:% d'% (nazwa pliku, bielizna) print cmd o, e = p.communicate (cmd) p.communicate ('kontynuuj') Powinno działać, a ja użyłem podobnego wcześniej, ale nadal daje ValueError: Operacja I/O w zamkniętym pliku po pierwszym komunikacie ... –
- 1. Inteligentne uruchamianie domyślnego edytora z poziomu programu Python CLI?
- 2. Jednoczesne uruchamianie konsoli instrumentów i debugowania
- 3. Uruchamianie Pythona interaktywnie z poziomu Sublime Text 2
- 4. Dane wejściowe konsoli PHPstorm nie działają podczas sesji debugowania
- 5. Używanie niestandardowej konsoli do debugowania aplikacji konsoli programu Visual Studio
- 6. Uruchamianie migracji z konsoli szyn
- 7. Uruchamianie programu java z innego programu java
- 8. Uruchamianie scrapy z poziomu skryptu Python - eksporter CSV nie działa
- 9. Uruchamianie OpenCV z Pythona virtualenv
- 10. Uruchamianie plików jar z Pythona
- 11. Uruchamianie programu Matlab z argumentami
- 12. Uruchamianie nowej sesji użytkownika z usługi
- 13. Jak echo do konsoli debugowania z php
- 14. Uruchamianie MySQL z poziomu wiersza poleceń
- 15. Uruchamianie hello.py z poziomu procesu Android
- 16. Uruchamianie wielu aplikacji konsoli z pliku wsadowego
- 17. Uruchamianie konsoli R z Sublime Text 2
- 18. uruchamianie trwałego skryptu Pythona z systemd?
- 19. Zakończono uruchamianie tabulatora Pycharm IPython (w konsoli pythona)
- 20. Rejestrowanie w języku Python: wyświetlanie tylko informacji z poziomu debugowania
- 21. Program Logcat nie wyświetla komunikatów poziomu debugowania
- 22. Okno debugowania programu nie zostanie zamknięte
- 23. Otwieranie dowolnego pliku z poziomu programu java
- 24. Jak usunąć instrukcje debugowania dzienników z programu
- 25. Dokumentacja klasy .NET z poziomu programu PowerShell?
- 26. Znajdź ścieżkę nagłówka python z poziomu Pythona?
- 27. Testowanie rodzimych wersji programu Visual Studio: Wyjście debugowania/konsoli?
- 28. Uruchamianie programu IDL z bash ze zmiennymi
- 29. nie można uruchomić z poziomu Pythona binarny AWS lambda funkcji
- 30. Jak korzystać z youtube-DL z programu Pythona
Więc nie chcesz używać wiersza poleceń, a nie chcesz edytować źródła ... o czym myślisz w inny sposób? – Amber