回溯是由Python提供的消息或信息,或者与一些数据一起的一般报告,它帮助我们了解在我们的程序中发生的错误。在技术上,它也被称为**引发异常**。对于任何开发工作,错误处理是编写程序时的关键部分之一。因此,处理错误的第一步是了解我们在代码中最常遇到的错误。
回溯为我们提供了大量的信息和一些关于运行程序时发生的错误的信息。因此,对最常见的错误有一个大致的了解是非常重要的。
回溯通常被称为某些其他名称,如 堆栈跟踪,backtrace, 或堆栈回溯。在所有的编程语言中,堆栈是一个抽象的概念,它只是指在系统的内存或处理器的核心中的一个地方,在那里指令正在被逐一执行。而每当在执行代码时出现错误,回溯就会试图告诉我们它的位置以及在执行这些指令时遇到的错误种类。
在Python中最常见的一些回溯信息
这里列出了我们在Python中遇到的最常见的回溯。随着本文的深入,我们还将尝试理解这些错误的一般含义:
- 语法错误(SyntaxError
- 名称错误(NameError
- 索引错误
- 类型错误
- 属性错误(AttributeError
- 密钥错误
- 值错误
- 模块未找到和导入错误
Python 中回溯的一般概述
在浏览最常见的回溯类型之前,让我们试着对一般堆栈回溯的结构做一个概述:
# defining a function
def multiply(num1, num2):
result = num1 * num2
print(results)
# calling the function
multiply(10, 2)
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 6, in <module>
multiply(10, 2)
File "d:\Python\traceback.py", line 3, in multiply
print(results)
NameError: name 'results' is not defined. Did you mean: 'result'?
解释:
Python试图帮助我们,给我们提供所有关于执行程序时发生的错误的信息。输出的最后一行说,这应该是一个NameError ,甚至给我们建议了一个解决方案**。** Python 还试图告诉我们可能是错误来源的行号。
我们可以看到,我们的代码中有一个变量名称不匹配。我们没有使用**"result",正如我们先前在代码中声明的那样,而是写成了"results",**这在执行程序时抛出了一个错误。
所以,这就是Python中Traceback的一般结构层次,这也意味着Python的Traceback应该从下往上读,这在其他大多数编程语言中是不一样的。
了解回溯
1.语法错误(SyntaxError
所有的编程语言都有其特定的语法。如果我们漏掉了这种语法,程序就会抛出一个错误。代码必须首先被解析,然后才会给我们提供所需的输出。 因此,我们必须确保正确的语法,以使其正确运行。
让我们试着看看Python引发的SyntaxError异常:
# defining a function
def multiply(num1, num2):
result = num1 * num2
print "result"
# calling the function
multiply(10, 2)
输出:
File "d:\Python\traceback.py", line 4
print "result"
^^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
解释:
当我们试图运行上面的代码时,我们看到Python提出了一个SyntaxError 异常。要在Python3.x中打印输出,我们需要用小括号把它包起来。我们也可以看到错误的位置,**"^"**符号显示在我们的错误下面。
2.名称错误
在编写任何程序时,我们都会声明变量、函数和类,并将模块导入其中。在我们的程序中使用这些东西时,我们需要确保所声明的东西应该被正确引用。相反,如果我们犯了某种错误,Python 将抛出一个错误并引发一个异常。
让我们看看Python中NameError的一个例子:
# defining a function
def multiply(num1, num2):
result = num1 * num2
print(result)
# calling the function
multipli(10, 2)
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 8, in <module>
multipli(10, 2)
NameError: name 'multipli' is not defined. Did you mean: 'multiply'?
解释:
我们的回溯说**"multipli "这个名字没有定义,这是一个NameError**。我们没有定义变量**"multipli",** 因此发生了这个错误。
3.索引错误
在Python中,与索引一起工作是一个非常常见的模式。我们必须在Python中遍历各种数据结构,对它们进行操作。索引标志着一个数据结构的序列,如列表或元组。每当我们试图从我们的数据结构中不存在的系列或序列中检索某种索引数据时,Python 都会抛出一个错误,说我们的代码中存在一个IndexError 。
让我们看看它的一个例子:
# declaring a list
my_list = ["apple", "orange", "banana", "mango"]
# Getting the element at the index 5 from our list
print(my_list[5])
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 5, in <module>
print(my_list[5])
IndexError: list index out of range
解释:
我们的回溯说,我们在第 5 行有一个IndexError 。从我们的堆栈跟踪可以看出,我们的列表在索引 5 处不包含任何元素,因此它超出了范围。
4.类型错误
当试图执行一个操作或使用一个函数时,在该操作中一起使用了错误类型的对象,Python 会抛出一个TypeError。
让我们看一个例子:
# declaring variables
first_num = 10
second_num = "15"
# Printing the sum
my_sum = first_num + second_num
print(my_sum)
输出
Traceback (most recent call last):
File "d:\Python\traceback.py", line 6, in <module>
my_sum = first_num + second_num
TypeError: unsupported operand type(s) for +: 'int' and 'str'
解释:
在我们的代码中,我们正试图计算两个数字的总和。但是Python引发了一个异常,说操作数**"+"** 在第6行有一个TypeError 。堆栈跟踪告诉我们,一个整数和一个字符串的相加是无效的,因为它们的类型不匹配。
5.5.AttributeError
每当我们试图访问一个对象上没有的属性时,Python 都会抛出一个Attribute Error。
让我们看一个例子:
# declaring a tuple
my_tuple = (1, 2, 3, 4)
# Trying to append an element to our tuple
my_tuple.append(5)
# Print the result
print(my_tuple)
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 5, in <module>
my_tuple.append(5)
AttributeError: 'tuple' object has no attribute 'append'
解释:
Python 说在第 5 行有一个对象**"tuple"的AttributeError**。因为**图元是不可改变的数据结构**,而我们正试图对它使用 "append "方法。因此,这里有一个由 Python 提出的异常。元组对象没有 "append "属性,因为我们正试图改变它,这在Python中是不允许的。
6.6.KeyError
Dictionary是Python中的另一个数据结构。我们在我们的程序中一直在使用它。它是由Key:值 对组成,我们需要在需要的时候访问这些键和值。但是如果我们试图在我们的字典中搜索一个不存在的键,会发生什么?
让我们试试使用一个不存在的键,看看 Python 对此有什么看法:
# dictionary
my_dict = {"name": "John", "age": 54, "job": "Programmer"}
# Trying to access info from our dictionary object
get_info = my_dict["email"]
# Print the result
print(get_info)
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 5, in <module>
get_info = my_dict["email"]
KeyError: 'email'
解释:
在上面的例子中,我们试图访问 key "email" 的值。好吧,Python 在我们的字典对象中搜索键 "email" 并引发了一个带有堆栈跟踪的异常。回溯说,在我们程序的第 5 行有一个KeyError 。所提供的键在指定的对象中无处可寻,因此出现了错误。
7.7.ValueError
ValueError异常是由Python引发的,每当在指定的数据类型中出现一个不正确的值时。提供的参数的数据类型可能是正确的,但是如果它不是一个合适的值,Python 将会为此抛出一个错误。
让我们看一个例子:
import math
# Variable declaration
my_num = -16
# Check the data type
print(f"The data type is: {type(my_num)}") # The data type is: <class 'int'>
# Trying to get the square root of our number
my_sqrt = math.sqrt(my_num)
# Print the result
print(my_sqrt)
输出:
The data type is: <class 'int'>
Traceback (most recent call last):
File "d:\Python\traceback.py", line 10, in <module>
my_sqrt = math.sqrt(my_num)
ValueError: math domain error
解释一下:
在上面的例子中,我们试图用Python中内置的数学模块来获得一个数字的平方根。我们使用正确的数据类型**"int "作为我们函数的参数,但是Python抛出了一个以ValueError**为异常的跟踪结果。
这是因为我们不能得到一个负数的平方根,因此,我们的参数是一个不正确的值,Python告诉我们这个错误,在第10行说这是一个ValueError 。
8.ImportError 和 ModuleNotFoundError
ImportError异常由 Python 提出,当导入一个不存在的特定模块时出现错误。ModuleNotFound异常是在为模块指定的路径无效或不正确时出现的。
让我们试着看看这些错误的表现。
ImportError 例子
# Import statement
from math import addition
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 2, in <module>
from math import addition
ImportError: cannot import name 'addition' from 'math' (unknown location)
ModuleNotFoundError 例子
import addition
输出:
Traceback (most recent call last):
File "d:\Python\traceback.py", line 1, in <module>
import addition
ModuleNotFoundError: No module named 'addition'
解释:
ModuleNotFoundError 是 ImportError 的一个子类,因为它们都输出类似的错误,并且可以通过 Python 中的 try 和 except 块来避免。
总结
在这篇文章中,我们回顾了我们在编写Python代码时遇到的最常见的错误或回溯类型。在我们编写的任何程序中犯错或引入错误,对于所有级别的开发者来说都是非常常见的。Python是一种非常流行的、用户友好的、易于使用的语言,它有一些很好的内置工具,可以在我们开发东西时尽可能地帮助我们。回溯是这些工具中的一个很好的例子,也是学习Python时需要了解的一个基本概念。