2017-12-13 118 views
12

Mam dużą starszą metodę Pythona, która zawiera około dwudziestu return instrukcji. Ta metoda nie powinna zwracać None, ale robi to. Jest powtarzalny w prostym przypadku testowym.Debugowanie, w którym zwracana jest metoda Brak

Do tej pory użyłem debuggera i przeszedłem przez linię kodu po linii, aby znaleźć zgodną instrukcję return.

Ale czy jest łatwiejszy sposób?

Czy istnieje sposób podniesienia wyjątku, gdy tylko metoda zwróci None?

i Oczywiście muszę zobaczyć wiersz zawierający instrukcję return.

przykład:

def big_method(arg1, some_var): 
    #.... many returns 
    if arg1: 
     return some_var # <------ 
    #... many returns 


assert not big_method(True, None) is None 

Powyżej prosty fragment kodu. Rezultat:

Traceback (most recent call last): 
    File "/home/modwork_vums_d/src/manyreturns.py", line 8, in <module> 
    assert not big_method(True, None) is None 
AssertionError 

Przede traceback nie pomaga bardzo dużo, ponieważ chcę zobaczyć linię wewnątrzbig_method(). W powyższym przykładzie chcę zobaczyć, który z nich oznaczono jako <------.

Używam PyCharm, ale czysty pyton lub inne rozwiązanie jest mile widziane.

Tylko dla rekordów. Istnieje kolejne pytanie, które próbuje włączyć tę funkcję w PyCharm: PyCharm: Debugging: r(eturn) Continue execution until the current function returns

+0

Istnieje możliwe rozwiązanie: https://stackoverflow.com/a/1156048/5588279. – Sraw

+0

Zastanawiam się, że byłoby to możliwe, ramka do wykonania big_method została już odzyskana. – georgexsh

+0

może mógłbyś wykorzystać funkcję śledzenia tłumacza, aby nagrać ścieżkę wykonania wywoływanej funkcji, a następnie wydrukować, gdy zewnętrzna asercja nie powiodła się. – georgexsh

Odpowiedz

14

PDB ma r(eturn) polecenia dla tego potrzebował:

r (eturn) Kontynuuj realizację aż prąd powraca funkcyjnych.

przykład:

> /Users/georgexsh/wasteland/tmp/app.py(6)<module>() 
-> assert not big_method(True, None) is None 
(Pdb) s 
--Call-- 
> /Users/georgexsh/wasteland/tmp/app.py(1)big_method() 
-> def big_method(arg1, some_var): 
(Pdb) r 
--Return-- 
> /Users/georgexsh/wasteland/tmp/app.py(3)big_method()->None 
-> return some_var 

zobaczyć bardziej szczegółowo w pdb doc.

0

jeśli możesz zmienić kod źródłowy, to będzie to łatwe. Ale pozwoli ci tylko uzyskać numer linii i musi się zmienić wszystkie oświadczenie zwrotne.

#!/usr/bin/env python 
import os 
import sys 
import inspect 
def get_head_info(): 
    try: 
     raise Exception 
    except: 
     f = sys.exc_info()[2].tb_frame.f_back 
    return '%s, %s' % (f.f_code.co_name, str(f.f_lineno)) 

def big_method(arg1, some_var): 
    if arg1: 
     return (print(get_head_info()), some_var) 
    return (print(get_head_info()), True) 
if __name__ == '__main__': 
    assert not big_method(True, None)[1] is None 

w python3.5 na win10, będzie się

big_method, 17 
Traceback (most recent call last): 
    File "C:\test.py", line 21, in <module> 
    assert not big_method(True, None)[1] is None 
AssertionError 

return (print(get_head_info()), some_var) to punkt, gdy spust był powrót, to najpierw ocenić oświadczenie druku, wydrukować numer wiersza (w tym sprawa 17), następnie uzyskaj wartość Brak, w końcu otrzymasz (None, some_var).

+0

Nie rozumiem' return (print ('% s '% (get_head_info())), True) i zawiera błąd składni. Czy jesteś pewien, że widzę, co się dzieje z 'return None'? – guettli

+0

to działa w python 3.5, kluczowy punkt tutaj to get_head_info metoda, to wydrukuje numer linii, gdzie go nazwiesz. – obgnaw

+0

Myślę, że to nie rozwiąże mojego problemu. Mogę użyć "assert 0", jeśli chcę zobaczyć aktualną linię interpretera. Pytanie brzmi: na jakiej linii był tłumacz przed bieżącą linią? To ujawni, które z 20 instrukcji return wewnątrz metody big_method() zostało użyte. – guettli

0

Dla mnie najprościej jest użyć dekoratora, który sprawdzi wyjście twojej funkcji.Mały przykład:

def check_none_in_response(func): 
    def wrapper(arg1, some_var): 
     rs = func(arg1, some_var) 
     assert rs is not None 
     return rs 

    return wrapper 

Zastosowanie:

@check_none_in_response 
<your method> 

Hope, to pomoże.

+0

Przepraszam, myślę, że źle zrozumiałeś moje pytanie. Pytanie brzmi: które z dwudziestu zwrotów w big_method() zostało użyte? – guettli

+0

Witam, przepraszam za to. Mój błąd. –

+0

to jest w porządku. Właśnie dlatego prawie nigdy nie głosuję w dół. Błędy mogą się zdarzyć. Dlaczego nie usunąć odpowiedzi? – guettli