Отладка, где метод возвращает Нет
У меня есть большой старый метод Python, содержащий около двадцати return
операторов.
Метод не должен возвращать None
, но он делает это. Он повторяется в простом случае.
До сих пор я использовал отладчик и прошел через строку кода, чтобы найти соответствующий оператор return.
Но есть ли более простой способ?
Есть ли способ повысить исключение, как только метод возвращает None?
и, конечно, мне нужно увидеть строку, содержащую оператор return.
Пример:
def big_method(arg1, some_var):
#.... many returns
if arg1:
return some_var # <------
#... many returns
assert not big_method(True, None) is None
Выше приведен фрагмент кода. Результат:
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
Выше трассировка не очень помогает, так как я хочу видеть строку внутри big_method()
. В приведенном выше примере я хочу видеть, что я отмечен <------
.
Я использую PyCharm, но приветствуется чистый python или другое решение.
Только для записей. Существует следующий вопрос, который пытается включить эту функцию в PyCharm: PyCharm: Debugging: r (eturn) Продолжить выполнение до тех пор, пока текущая функция не вернется
Ответы
Ответ 1
pdb имеет команду r(eturn)
для этой необходимости:
г (eturn) Продолжайте выполнение до тех пор, пока не вернется текущая функция.
Пример:
> /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
Подробнее см. pdb doc.
Ответ 2
если вы можете изменить исходный код, тогда это будет легко. но это позволит вам получить номер строки и изменить все операторы return.
#!/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
в python3.5 на win10, он получит
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)
Это точка, когда возврат был триггером, он сначала оценит оператор печати, напечатает номер строки (в этом случае 17), а затем получит значение None, наконец вы получите (None, some_var)
.
Ответ 3
Для меня самый простой способ - использовать декоратор, который будет проверять вывод вашей функции. Маленький пример:
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
Использование:
@check_none_in_response
<your method>
Надеюсь, это поможет вам.