python
- 程序抛出异常时,python解释器会提供一个跟踪信息,这个信息从最近的事件(即最后发生的函数调用)开始,按照调用顺序的相反方向,一路回溯到程序的起点。这个过程基本上是在跟踪函数调用的栈结构
"Traceback (most recent call last):"表明接下来的内容是调用栈的逆序列表,然后列出函数调用的具体顺序
错误信息示例解释:
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。来看看
err.py:# err.py:deffoo(s): return 10 / int(s) defbar(s): return foo(s) * 2 defmain(): bar('0') main()
执行,结果如下:
$ python3 err.py Traceback (most recentcalllast): File "err.py", line 11,in <module> main() File "err.py", line 9,in main bar('0') File "err.py", line 6,in bar return foo(s) * 2 File "err.py", line 3,in foo return 10 /int(s) ZeroDivisionError: divisionby zero
出错并不可怕,可怕的是不知道哪里出错了。解读错误信息是定位错误的关键。我们从上往下可以看到整个错误的调用函数链:
错误信息第1行:
Traceback (most recentcalllast):
告诉我们这是错误的跟踪信息。
第2~3行:
File "err.py", line 11, in <module> main()
调用
main()出错了,在代码文件err.py的第11行代码,但原因是第9行:File "err.py", line 9,in main bar('0')
调用
bar('0')出错了,在代码文件err.py的第9行代码,但原因是第6行:File "err.py", line 6,in bar return foo(s) * 2
原因是
return foo(s) * 2这个语句出错了,但这还不是最终原因,继续往下看:File "err.py", line 3,in foo return 10 / int(s)
原因是
return 10 / int(s)这个语句出错了,这是错误产生的源头,因为下面打印了:ZeroDivisionError: integer divisionor modulo by zero
捕获错误
logging 记录错误
- 如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
Python内置的
logging模块可以非常容易地记录错误信息- 同样是出错,但程序打印完错误信息后会继续执行,并正常退出
- 通过配置,
logging还可以把错误记录到日志文件里,方便事后排查。
import logging def foo(s): return 10 / int(s) def bar(s): return foo(s) * 2 def main(): try: bar('0') except Exception as e: logging.exception(e) main() print('END') # 输出 # ERROR:root:division by zero # Traceback (most recent call last): # File "C:\Users\sonow\AppData\Local\Temp\ipykernel_11232\3551389354.py", line 11, in main # bar('0') # File "C:\Users\sonow\AppData\Local\Temp\ipykernel_11232\3551389354.py", line 7, in bar # return foo(s) * 2 # File "C:\Users\sonow\AppData\Local\Temp\ipykernel_11232\3551389354.py", line 4, in foo # return 10 / int(s) # ZeroDivisionError: division by zero # END
抛出错误
- 用
raise语句抛出一个错误的实例
- 只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如
ValueError,TypeError),尽量使用Python内置的错误类型。
错误列表
OSError

Windows中通过 netstat -anto 命令查看端口占用情况,找到PID,去任务管理器里查看使用该端口的应用进程
AttributeError
- module 'unittest.result' has no attribute 'decode’【模块中没有改属性】
TypeError
- TypeError: sort_data() got an unexpected keyword argument 'data’【调用函数时传入一个并未定义的参数】
- TypeError: FooChild1.init() takes 1 positional argument but 2 were given【调用该方法时传递了 2 个位置参数,但该方法只接受 1 个位置参数】
- TypeError: Person.say_hi() takes 2 positional arguments but 3 were given
- 【原因】此方法为实例成员函数,调用时类会自动传入一个self参数。在定义时未传入self参数且仅接受自定义的两个参数,实例化该类后调用该方法正确传入了两个参数,加上类自动传入的self参数就有3个参数了
- 【解决方案】1、将此方法定义为静态成员函数。2、修改定义,手动传入self参数
- TypeError: Cannot create a consistent method resolution order (MRO) for bases … 【定义类时的继承问题,创建MRO列表错误(从左至右的方法解析顺序列表),违反了MRO单调性原则(该原则要求MRO中的所有子类均在其父类前面)】
TypeError: add() missing 2 required positional arguments: 'a' and 'b’【同时定义了两个同名的方法,python只能识别最近一次定义的版本,由于第二个 add 函数定义覆盖了第一个函数,当调用 print(add()) 时,Python 会期待你提供两个参数给 add 函数】
- 【根本原因】python不支持方法重载,意味着不能在同一个作用域内定义两个具有相同名称但参数不同的函数
- 【解决方案】通过设置默认值来实现
def add(): return 1+2 def add(a, b): return a+b if __name__ == '__main__': print(add()) print(add(3, 5))
使用循环来接收套接字的响应内容时,每次处理 1k 字节,其中报错“'utf-8' codec can't decode byte 0xef in position 4095: unexpected end of data”
- 【原因】由于响应内容的大小超过 1k 字节,每次处理1k导致其中的二进制编码被中断,进而使用 utf-8 无法对内容进行解码
- 【解决方案】使用二进制字符接收每次处理的 1k 字节,在接收到全部响应内容后再使用 utf-8 对内容进行解码
VSCode
问题
无法通过相对路径读取文件
- 【问题】明明在一个文件夹中,通过相对路径就是无法读取,提示No such file or directory:XXX
- 【原因】vscode默认相对路径无效
- 【解决方法】修改设置,使终端在py文件当前目录下打开
- 在设置中搜索teminal,选择用户→python
- 勾选Execute In File Dir
vs code中运行python文件是在终端运行,默认打开终端目录是当前工作区的根目录,运行该工作区子文件夹中的py文件时,如果含有相对路径,会报错。如运行python工作区中.jumping_ball 文件夹内的ball.py,终端路径为python根目录,会提示找不到ball.jpg
- Python
- .jumping_ball
- ball.jpg
- ball.py
网上的方法是修改launch.json中的 “cwd” 为 “${fileDirname}” ,亲测无用。