# 调试

``````# err.py
def foo(s):
n = int(s)
print '>>> n = %d' % n
return 10 / n

def main():
foo('0')

main()
``````

``````\$ python err.py
>>> n = 0
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
``````

`print`最大的坏处是将来还得删掉它，想想程序里到处都是`print`，运行结果也会包含很多垃圾信息。所以，我们又有第二种方法。

### 断言

``````# err.py
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n

def main():
foo('0')
``````

`assert`的意思是，表达式`n != 0`应该是`True`，否则，后面的代码就会出错。

``````\$ python err.py
Traceback (most recent call last):
...
AssertionError: n is zero!
``````

``````\$ python -O err.py
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
``````

### logging

`print`替换为`logging`是第3种方式，和`assert`比，`logging`不会抛出错误，而且可以输出到文件：

``````# err.py
import logging

s = '0'
n = int(s)
logging.info('n = %d' % n)
print 10 / n
``````

`logging.info()`就可以输出一段文本。运行，发现除了`ZeroDivisionError`，没有任何信息。怎么回事？

``````import logging
logging.basicConfig(level=logging.INFO)
``````

``````\$ python err.py
INFO:root:n = 0
Traceback (most recent call last):
File "err.py", line 8, in <module>
print 10 / n
ZeroDivisionError: integer division or modulo by zero
``````

`logging`的另一个好处是通过简单的配置，一条语句可以同时输出到不同的地方，比如console和文件。

### pdb

``````# err.py
s = '0'
n = int(s)
print 10 / n
``````

``````\$ python -m pdb err.py
> /Users/michael/Github/sicp/err.py(2)<module>()
-> s = '0'
``````

``````(Pdb) l
1     # err.py
2  -> s = '0'
3     n = int(s)
4     print 10 / n
[EOF]
``````

``````(Pdb) n
> /Users/michael/Github/sicp/err.py(3)<module>()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/sicp/err.py(4)<module>()
-> print 10 / n
``````

``````(Pdb) p s
'0'
(Pdb) p n
0
``````

``````(Pdb) n
ZeroDivisionError: 'integer division or modulo by zero'
> /Users/michael/Github/sicp/err.py(4)<module>()
-> print 10 / n
(Pdb) q
``````

### pdb.set_trace()

``````# err.py
import pdb

s = '0'
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print 10 / n
``````

``````\$ python err.py
> /Users/michael/Github/sicp/err.py(7)<module>()
-> print 10 / n
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
File "err.py", line 7, in <module>
print 10 / n
ZeroDivisionError: integer division or modulo by zero
``````

### IDE

http://www.jetbrains.com/pycharm/