import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug("Just a debug message! DON'T PANIC")
logging.info("Here, sir, have my info")
logging.critical("OMGOMGOMGOMG")
Нива на логване, по ред на страшност:
Нивото по подразбиране е WARNING
logging.basicConfig(
level=logging.DEBUG,
filename='debug.txt',
format='%(asctime)s %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
Използвайте logging вместо print() когато пишете пограма която е по-голяма от две прости функции, за да знаете винаги какво се случва.
Трудно е да се дебъгва с print()/logging когато програмата забива или отказва да работи
>>> make_a_sandwich(for=me)
'NO!'
Segmentation fault (core dumped)
На помощ идват дебъгерите!
python -m pdb buggy.py
> /buggy.py(1)<module>()
-> from doomsday import Appocalypse
(Pdb)
>>> import pdb
>>> from doomsday import Appocalypse
Traceback (most recent call last):
File "/appocalypse.py", line 1, in <module>
DeathAndDestruction
>>> pdb.pm() # Post mortem
Breakpoint е място в което изпълнението на кода спира и се пуска дебъгера.
from copy import deepcopy
def bubblesort(data):
data = deepcopy(data)
for repeat in range(0, len(data)-1):
index = 0
while index < len(data) - 1:
if data[index] > data[index + 1]:
# Something smells fishy here
import pdb; pdb.set_trace()
data[index], data[index + 1] = data[index + 1], data[index]
index += 1
return data
Добавяне на breakpoint без пипане на кода
$ python3 -m pdb python.py
> /python.py(1)<module>()
-> from food import sandwich
(Pdb) break 42
Breakpoint 1 at /python.py:42
(Pdb) break 84
Breakpoint 2 at /python.py:84
Изглеждат много и страшни, но половината са синоними
(Pdb) help
Documented commands (type help <topic>):
========================================
EOF cl disable interact next return u where
a clear display j p retval unalias
alias commands down jump pp run undisplay
args condition enable l print rv unt
b cont exit list q s until
break continue h ll quit source up
bt d help longlist r step w
c debug ignore n restart tbreak whatis
cProfile.run() приема произволен питонски код като низ
import cProfile
cProfile.run("answer_to_the_question_of_life_universe_and_everything()")
import re
cProfile.run('re.compile("6x9=?|42")')
Можете да пуснете и цяла програма:
$ python -m cProfile -o <output-file-name> <script-name> <script-options>
def ack(m, n):
if m == 0:
return n+1
if n == 0:
return ack(m-1, 1)
return ack(m-1, ack(m, n-1))
import cProfile
cProfile.run("print(ack(3,4))")
$ pip install runsnakerun
$ runsnake <cProfile dump>
Дълго време в Питон нямаше стандартен модул за проследяване на паметта
От Python 3.4 вече има tracemalloc
import tracemalloc
tracemalloc.start()
# ... балона се надува, надувайте момчета ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
# top 10 files allocating the most memory
for stat in top_stats[:10]:
print(stat)