Browse Source

Add Lab03-Lab06

master
SU Bin 2 years ago
parent
commit
3a88443c6c
6 changed files with 2035 additions and 62 deletions
  1. +32
    -41
      Lab01.ipynb
  2. +16
    -21
      Lab02.ipynb
  3. +595
    -0
      Lab03.ipynb
  4. +628
    -0
      Lab04.ipynb
  5. +419
    -0
      Lab05.ipynb
  6. +345
    -0
      Lab06.ipynb

+ 32
- 41
Lab01.ipynb View File

@ -1,21 +1,15 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {},
"source": [
"实践1 python初印象\n",
"学习目标\n",
"1.熟悉Jupyter lab交互开发环境\n",
"2.掌握Python 语句的编写,运行和修改\n",
"3.阅读Python微程序,尝试模仿改写程序"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 实践1 初识python程序"
"# 实践1 python初印象\n",
"\n",
"## 学习目标\n",
"1. 熟悉Jupyter lab交互开发环境\n",
"2. 掌握Python 语句的编写,运行和修改\n",
"3. 阅读Python微程序,尝试模仿改写程序"
]
},
{
@ -23,26 +17,34 @@
"metadata": {},
"source": [
"## 1. 安装Jupyter lab \n",
" 如要在自己电脑本地使用 Jupyter Lab 需要在命令提示符窗口(CMD)先用 Python 的包管理工具 pip 来安装: \n",
" pip install jupyterlab \n",
" 然后就可以用 \n",
" jupyter lab \n",
" 来运行 Jupyter Lab,打开 notebook 进行交互式编程的尝试"
"如要在自己电脑本地使用 Jupyterlab 需要在命令提示符窗口(CMD)先用 Python 的包管理工具 pip 来安装:\n",
"\n",
"`pip install jupyterlab` \n",
"\n",
"然后就可以用\n",
"\n",
"`jupyter lab`\n",
"\n",
"来运行 Jupyterlab,打开 notebook 进行交互式编程的尝试。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.创建使用Notbook文件 \n",
" (1)Notbook文件 \n",
" 菜单命令 New Notebook 创建一个新的Notbook文件 \n",
" (2)单元格 \n",
" Notbook文件是有若干单元格构成,单元格的类型可区分为:code、Markdown、RAW。 \n",
" code类型的单元格中可以编写一条或多条python语句。按上方三角形Run按钮执行,或快捷键ctrl+enter。\n",
" RAW类型的单元格是纯文本 \n",
" Markdown类型的单元格支持Markdown格式,请自行查阅。 \n",
" (3)使用工具栏命令可以增加,复制,删除,移动单元格。 "
"## 2.创建使用Notbook文件\n",
"\n",
"(1)Notbook文件 \n",
"File菜单 -> New Notebook 创建一个新的Notbook文件 \n",
"\n",
"(2)单元格 \n",
"Notbook文件是有若干单元格构成,单元格的类型可区分为:Code(代码)、Markdown、RAW。 \n",
"\n",
"Code类型的单元格中可以编写一条或多条python语句。按上方三角形运行(Run)按钮执行,或快捷键Ctrl+Enter;\n",
"RAW类型的单元格是纯文本;\n",
"Markdown类型的单元格支持Markdown格式,请自行查阅。 \n",
"\n",
"(3)使用工具栏命令可以增加,复制,删除,移动单元格。 "
]
},
{
@ -75,20 +77,9 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"重要的事情说三遍\n",
"Hello Python World!\n",
"Hello Python World!\n",
"Hello Python World!\n"
]
}
],
"outputs": [],
"source": [
"# 示例2 多条语句\n",
"#Fl1-1 重要的事情说三遍\n",
@ -388,7 +379,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@ -402,7 +393,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
"version": "3.9.5"
}
},
"nbformat": 4,

+ 16
- 21
Lab02.ipynb View File

@ -4,24 +4,19 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"实践2 Python基本语法 \n",
"学习目标 \n",
"1.值具有类型,了解值的类型很重要; \n",
"2.理解变量是值的抽象,可以帮助我们处理用户输入的任何值; \n",
"3.掌握赋值语句,赋值语句是值与变量、变量与变量之间的桥梁。 \n",
"4.掌握基本运算,操作符是对数据进行操作的一些符号,最常用的有算术运算、大小比较、赋值、逻辑运算等; \n",
"5.了解代码注释的语法和意义; \n",
"6.了解浮点表示误差和规避方法; \n",
"7.了解 Python 中字符串的表示方法以及转义符;\n",
"8.了解如何使用 f-string;\n",
"9.掌握输入输出语句,输入输出语句提供了程序与用户的交互渠道,程序可以根据用户的输入,输出对应的结果。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Python基本语法"
"# 实践2 Python基本语法 \n",
"\n",
"## 学习目标 \n",
"\n",
"1. 值具有类型,了解值的类型很重要; \n",
"2. 理解变量是值的抽象,可以帮助我们处理用户输入的任何值; \n",
"3. 掌握赋值语句,赋值语句是值与变量、变量与变量之间的桥梁。 \n",
"4. 掌握基本运算,操作符是对数据进行操作的一些符号,最常用的有算术运算、大小比较、赋值、逻辑运算等; \n",
"5. 了解代码注释的语法和意义; \n",
"6. 了解浮点表示误差和规避方法; \n",
"7. 了解 Python 中字符串的表示方法以及转义符;\n",
"8. 了解如何使用 f-string;\n",
"9. 掌握输入输出语句,输入输出语句提供了程序与用户的交互渠道,程序可以根据用户的输入,输出对应的结果。"
]
},
{
@ -1224,7 +1219,7 @@
]
},
{
"cell_type": "raw",
"cell_type": "markdown",
"metadata": {},
"source": [
"请思考在哪些情况下,程序会运行出错?\n",
@ -1239,7 +1234,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@ -1253,7 +1248,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
"version": "3.9.5"
}
},
"nbformat": 4,

+ 595
- 0
Lab03.ipynb View File

@ -0,0 +1,595 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 实践3 函数与模块\n",
"\n",
"1. 理解函数的基本概念;\n",
"2. 掌握Python内置函数的使用;\n",
"3. 掌握Python标准模块的引入;\n",
"4. 掌握math模块中常用数学函数的使用;\n",
"5. 理解函数的定义和调用。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1.函数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"程序里的函数概念完全来自数学里的函数。我们先来看看数学里的函数。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 函数的基本概念"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在数学里,我们可以定义一个函数,函数有一些*自变量*,也就是一些**输入**,**函数定义**就是定义如何通过这些输入计算出*函数的值*,也就是**输出**。下面是个典型的函数定义的例子:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\n",
"\\begin{align}\n",
"f(a, b) = \\sqrt{a^2 + b^2}\n",
"\\end{align}\n",
"$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"函数定义好之后,随时可以用具体的值送进去算出一个具体的函数值,比如:\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\n",
"\\begin{align}\n",
"f(1, 2) = \\sqrt{5}\n",
"\\end{align}\n",
"$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\n",
"\\begin{align}\n",
"f(3, 4) = 5\n",
"\\end{align}\n",
"$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$\n",
"\\begin{align}\n",
"f(2, 6) = 2\\sqrt{10}\n",
"\\end{align}\n",
"$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"程序里的函数也是这样,我们先要定义函数,也就是定义它的名字(叫做 **函数名** *function name*)、若干输入变量(叫做 **参数** *argument*)以及如何通过输入变量算出函数的值(叫做 **返回值** *return value*);一旦定义好,就可以在程序的其他地方随时使用这个函数,给它具体的参数值,它就给出具体的返回值。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 调用现成的函数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们先看看怎么用函数,术语叫做函数**调用**(*call*),因为 Python 本身自带了很多已经定义好的函数,我们可以直接拿来用。其中有一些我们之前已经用过了:\n",
"* `print(a, b,...)`:在命令行输出界面打印输入的参数(可以是各种类型的数据);\n",
"* `type(x)`:返回参数 x 的数据类型;\n",
"* `abs(x)`:返回参数 x(整数或者浮点数)的绝对值。\n",
"\n",
"这几个都是 Python 的内置函数,可以直接用。我们下面来看两个其他的例子。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"第一个例子是另一个 Python 内置函数,叫做 `isinstance(x, c)`,它有两个输入参数,第一个是一个数据,第二个是一个数据类型,如果第一个数据是第二个数据类型,`isinstance` 函数返回 `True`,否则就返回 `False`。所以 `isinstance` 可以用来判断某个值或者变量是不是某种类型,下面是例子:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(a, int)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(a, float)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(g, float)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(True, str)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(True, bool)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance('abracadabra', str)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(True, bool) and not isinstance('abracadabra', float)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.模块\n",
"\n",
"第二个例子是 Python 的平方根函数 `math.sqrt(x)`,这个函数前面有个 `math`,这表示函数 `sqrt(x)` 不在 Python 的内置环境中,而是放在一个叫 `math` 的函数包(学名叫 **模块** *module*)里,关于模块我们以后会专门介绍。要使用这种函数,第一种方法是:\n",
"* 先 **引入**(*import*)对应的函数包;\n",
"* 使用时函数名前面要带上模块的名字,中间加个 `.`。\n",
"\n",
"就像下面这样:"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4.0"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import math\n",
"math.sqrt(16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"另外一种方法是,从对应的模块里指明引入这一个函数,使用时就不用带上模块名了:"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6.324555320336759"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from math import sqrt\n",
"sqrt(40)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们可以看到 `sqrt(x)` 函数可以接受整数或者浮点数输入,返回值是浮点数。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. 定义函数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"有了 `sqrt(x)` 这个函数,我们可以定义一个函数来实现前面举例的那个数学里的函数 `f(a, b)` 了。在 Python 里函数的定义以关键字 `def` 开始,后面依次是函数名、小括号括起来的参数列表和一个冒号,之后的代码就是函数的算法定义,直到关键字 `return` 开始的 **返回语句**,这个返回语句会终止函数的运行,并把 `return` 后面的值作为函数的返回值,回到调用函数的地方。看起来有点抽象,我们看看例子: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5.0\n"
]
}
],
"source": [
"from math import sqrt\n",
"\n",
"def f(a, b):\n",
" return sqrt(a**2 + b**2)\n",
"\n",
"result = f(3, 4)\n",
"print(result)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"上面的代码很短,但是很重要,我们务必要搞懂这里的每一个细节。\n",
"\n",
"首先第一行是引入 `sqrt(x)` 函数,因为我们下面定义的函数要用到它。\n",
"\n",
"然后是函数定义 `def f(a, b):`,关键字 `def` 打头,后面是函数名 `f`、参数列表 `(a, b)` 和一个冒号,这表示函数 `f` 接受两个参数,一个叫 `a` 一个叫 `b`。下面一行就是**函数体**(*function body*),里面可以写很多东西,只要最后有一个 `return` 指明函数返回值就行,注意 Python 的函数可以没有返回值(`return` 后面什么都不写就行了),也可以返回多个值(`return` 后面写多个值,用逗号隔开)。\n",
"\n",
"我们这个例子因为很简单,就一句话就能搞定:函数返回值等于 a 平方加 b 平方再开方。注意函数体的代码缩进了一些,和其他的行都是顶着行首书写不一样,这是 Python 的缩进规则要求的,下面的插播会做出解释。\n",
"\n",
"然后是调用函数的例子,它是这么进行的:\n",
"1. 首先用 3 和 4 作为参数来调用 `f()` 函数;\n",
"2. 函数 `f()` 开始执行,把值 3 赋给参数变量 a,4 赋给 b,然后执行函数体;\n",
"3. 函数体计算出返回值 5.0 并返回;\n",
"4. 用返回值 5.0 替换掉 `f()` 的位置,相当于执行赋值 `result = 5.0`\n",
"5. 用 5.0 作为参数值调用内置的 `print()` 函数,打印出 5.0(`print()` 没有返回值)。\n",
"\n",
"顺便说一句,熟练之后我们可以把后两行简化成一句 `print(f(3, 4))`,效果是完全一样的。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 插播:代码缩进"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"所谓代码缩进就是一行代码不顶格写,而是在行首空若干格再写。缩进可以很多层,比如 Python 中第一层缩进空四格,第二层缩进空八格,第三层缩进空十二格,依此类推。程序员都喜欢用“**等宽字体**(*fix-width font*)”,就是因为等宽字体在缩进时非常整齐美观。\n",
"\n",
"缩进是为了让代码层次更加鲜明地呈现出来。比如上面函数定义的代码,函数体的部分是“隶属于”函数定义 `def` 语句的,是它的组成部分,所以缩进一层表示这个从属关系;而后面的函数调用则不是,所以最后两行不缩进,和 `def` 语句平齐,代表是同一层级的代码。\n",
"\n",
"在 Python 中缩进是强制的,如果不进行正确的缩进,比如如果函数体没有正确的缩进,解释器会因为找不到必须的部分而报错。\n",
"\n",
"目前主流的程序编辑器都提供了自动缩进、自动排版的功能,在 VSCode 和 Jupyter Notebook 中书写代码时大部分时候都会自动正确的缩进,所以很方便。\n",
"\n",
"对于初学者来说,知道有这么回事,然后多看,慢慢就会习惯成自然,和多听多看学语言是差不多的道理。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.函数的调用 \n",
"函数定义后,未经调用,是不会执行的。需要时使用函数调用语句。 \n",
"在函数调用的时候要求传递对应的值给形参,这个传递的值称为实际参数,简称实参。参数是可选的,也就是说函数可以不包括参数,例如:random.random() 就不包含参数。 \n",
"根据函数是否有返回值,函数的调用也是不同的。如果函数有返回值,函数调用的时候需要安排接受返回值。 \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6.324555320336759"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 可以是赋值语句,将返回值赋值给一个变量\n",
"z = f(2,6)\n",
"z"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"50.0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 可以是表达式语句,将返回值作为表达式的一个数值,继续参加运算\n",
"z = f(3,4)*10\n",
"z\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"11.180339887498949"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 可以作为函数调用的实参\n",
"z=f(f(3,4),10)\n",
"z\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 函数的意义"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"函数是编程中最重要的概念之一。实现它有助于我们实现程序的“**模块化**(*modulization*)”,我们可以把特定的工作用一个函数来实现,然后在需要的地方反复地调用它。这是一种代码重用的方法,一个函数就好像乐高积木里的一个组件,我们可以通过组合各种不同功能的函数来实现复杂的目标。\n",
"\n",
"函数还是协作编程的基础。如果我们实现了一个很有用的函数,我们可以写一个文档说明函数的输入参数和返回值是什么,这样的文档叫做**调用接口**(*interface*),别人都可以照此使用我们写的函数,甚至不需要了解它是怎么实现的(比如我们就直接拿了 `math.sqrt()` 来用而不需要自己写一个)。函数天生就把自己的接口和实现分离开,让协作和复用成果更容易。\n",
"\n",
"**模块化** 和 **接口独立** 是编程时最重要的两个思维模型(没有之一),我们在后面还会深入介绍。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 小试身手\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### (1)使用math模块的数学函数。 \n",
"导入数学库math。然后输入以下表达式理解math中函数的使用,注意结果值的数据类型。 \n",
"math.sqrt(2*2+3*3)、 math.log10(100)、 math.exp(2)、math.fmod(4,3)、math.sin(2*math.pi)、\n",
"math.gcd(12,9)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[数学库math](https://docs.python.org/zh-cn/3/library/math.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### (2)自定义求矩形面积的函数"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#定义一个函数getArea(length,width),计算长为length,宽为width的矩形面积。 \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#试着用不同的方式调用getArea函数,验证函数的正确性\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

+ 628
- 0
Lab04.ipynb
File diff suppressed because it is too large
View File


+ 419
- 0
Lab05.ipynb
File diff suppressed because it is too large
View File


+ 345
- 0
Lab06.ipynb View File

@ -0,0 +1,345 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 实践6:异常处理\n",
"\n",
"## 学习目标:\n",
"\n",
"1. 了解程序处理用户或其他系统提供的输入时可能出现预期之外的异常状况,可以使用异常处理来捕获异常并进行应急处置;\n",
"2. 理解 Python 异常处理的模板含义;\n",
"3. 通过例子初步了解异常处理可能的应用场景。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"异常处理是个很重要,也有点难度的概念。我们先尝试理解基本的概念,后面再不断通过实践来加深掌握。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们前面说过,大多数程序的工作都是:接受输入,对输入进行处理,然后输出结果。这里有个很重要的理念,是所有资深程序员都习惯成自然的认知,那就是“输入是不可控的”,输入可能是用户通过键盘鼠标触控屏输入的,也可能是读取某个设备上一个程序的输出,简言之,都存在不可期的情况。\n",
"\n",
"假定我们期待用户或者某个程序给我们一个不为 0 的整数,我们要拿来做除数算出一个值,如果来的不是整数是个小数怎么办?或者就是个 0 怎么办?或者干脆就不是个数怎么办?\n",
"\n",
"还有依赖于外部设备的各种异常状况:如果我们从某个程序读一个数,但是那个程序死掉了,一直没给我们数,我们一直等着卡死在这里?或者我们要向打印机输出一个报表,但是打印机被人踢掉了电源线,一直不响应怎么办?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"所有这些错误都在程序运行时才会出现,程序写出来是没有错的,运行时出现奇怪的异常状况,程序又没有好好处理的话,就会出现灾难,这些运行时出现的异常状况就叫**运行时错误**(*runtime error*)或者**运行时异常**(*runtime exception*)。现代编程语言一般都提供标准的异常处理方案,让我们可以写程序来处理这类异常。\n",
"\n",
"Python 提供的异常处理机制可以用下面的模板来说明:\n",
"\n",
"```python\n",
"try:\n",
" # 把有可能出现异常的代码放在 try 后面\n",
" # 当出现异常时解释器会捕获异常\n",
" # 并根据异常的类型执行后面的对应代码块\n",
" do_something_nasty()\n",
"except ValueError:\n",
" # 如果发生 ValueError 类型的异常则执行这个代码块\n",
" pass\n",
"except (TypeError, ZeroDivisionError):\n",
" # 可以一次指定几个不同类型的异常在一起处理exceptions\n",
" # 如果出现 TypeError 或者 ZeroDivisionError 则执行这个代码块\n",
" pass\n",
"except:\n",
" # 所有上面没有专门处理的类型的异常会在这里处理\n",
" pass\n",
"else:\n",
" # 当且仅当 try 代码块里无异常发生时这个代码块会被执行\n",
" pass\n",
"finally:\n",
" # 无论发生了什么这个代码块都会被执行\n",
" # 通常这里是清理性的代码,比如我们在 try 里面打开一个文件进行处理\n",
" # 无论过程中有没有异常出现最后都应该关闭文件释放资源\n",
" # 这样的操作就适合在这里执行\n",
"```\n",
"\n",
"上面出现的关键字 `pass` 的意思是“什么也不做”,Python 语法需要有点什么,但是我们暂时什么都不想做的时候放上一个 `pass` 就可以了。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以 `try` 开始的异常处理结构可以包含所有这些模块,但并不是都必须有,但至少应该有一个 `except` 或者 `finally`。\n",
"\n",
"Python 有很多[内置的运行时错误类型](https://docs.python.org/3/library/exceptions.html#bltin-exceptions)可以直接使用,比如我们上面看到的:\n",
"* `TypeError`:当一个操作或者函数收到的参数类型不对,或者一个类型的对象不支持某个被请求的操作时抛出这个异常;\n",
"* `ValueError`:当一个操作或者函数收到的参数类型对但是值不合法时抛出这个异常;\n",
"* `ZeroDivisionError`:出现 0 作除数的情况时抛出这个异常。\n",
"\n",
"我们来看几个官方指引中的例子并稍作解释。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"while True:\n",
" try:\n",
" x = int(input('Please enter a number: '))\n",
" break\n",
" except ValueError:\n",
" print('Not a valid number. Try again...')\n",
"\n",
"print('Your number is:', x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这里用一个无限循环中的 `input()` 方法来获取用户输入,然后把输入的字符串用 `int()` 方法转换为一个整数;如果用户没有输入一个整数,`int()` 方法会抛出一个 `ValueError`,于是执行 `except ValueError` 后面的代码块,打印一个提示,然后继续 `while True`,再次提示用户输入;如果 `try` 代码段里第一句执行成功(用户输入成功转换为整数并赋值给 x 变量),那就继续执行后面一句 `break` 终止循环,继续执行其他代码(这时候 x 里面已经有了用户输入的整数)。\n",
"\n",
"在这里异常处理确保用户输入可以转换为整数且赋值给 x,否则就不会继续执行下去,经过这样的处理,在这段代码之后我们可以相当有把握的说:x 里面有个合法的、用户输入的整数值;同时用户不管怎么乱输入也不会对程序构成致命影响,我们预期到可能出现的问题,并做了合理处理。这就是异常处理的意义所在。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def this_fails():\n",
" x = 1/0\n",
"\n",
"try:\n",
" this_fails()\n",
"except ZeroDivisionError as err:\n",
" print('Handling run-time error:', err)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这个例子展示了用 `except ZeroDivisionError as err` 这样的语法来取得一个 `err` 对象,这个对象是系统定义的 `Exception` 类型或者子类,里面存放着发生异常时的具体上下文信息,可以打印出来也可以做别的处理。\n",
"\n",
"我们还可以从 `Exception` 派生出我们自己的异常类型,并使用 `raise` 关键字来在出现某种情况时抛出我们定义的异常,并在文档中做出清晰的说明。这样使用我们代码的其他程序员就知道什么情况是我们程序处理不了的,会抛出什么样的异常,并在调用端用捕获异常进行处理。\n",
"\n",
"建议学习 [关于 Python 异常处理的官方教程](https://docs.python.org/3/tutorial/errors.html) 来了解更多。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 案例 求直角三角形的直角边\n",
"程序实现功能为:让用户输入直角边和斜边的长度,输出第二条直角边的长度。\n",
"要求:提示用户所有的非法输入:非ASCII数字、直角边大于斜边、浮点数,并将这些非法输入所引起的异常用一个except子句匹配;异常处理完后,程序立刻终止。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"try:\n",
" a=int(input('直角边长度:'))\n",
" c=int(input('斜边长度:'))\n",
" print(f'直角边长度为 {a},斜边长度为 {c}')\n",
" print(f'第二条直角边长度为:{ math.sqrt(c**2-a**2)}')\n",
"except (ValueError):\n",
" print('请使用整数,斜边必须大于直角边')\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"直角边大于斜边所产生的对负数开根号、输入非ASCII正整数这两种错误,都会引发同样的异常——ValueError。用except扑捉ValueError,输出提示信息。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 小试身手"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. 运行下面程序段,认识默认异常处理器,总结异常名和产生异常的场合"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" for i in range(1,5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for1 + i"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"12/0"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"math.sqrt(-2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'1'+1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"1+'1'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a=5\n",
"str(a)+6"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x=10\n",
"y=2.5\n",
"f\"x={x:d},y={y:d}\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int('hello')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" true+5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"1000.1**333"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"2. 编写程序以完成如下两个表达式的计算\n",
"a/(a-b-1)\n",
"a**b\n",
"要求:a、b两变量中的数,由用户输入;它们可以是浮点数;捕捉用户的输入错误,除数不为零的错误,程序结束输出“结束”提示。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try:\n",
" a=float(input('a:'))\n",
" b=float(input('b:'))\n",
" print(f\"{a/(a-b-1)}\")\n",
" print(f\"{math.sqrt(a**2-b**2)}\"\")\n",
" \n",
"except_______ :\n",
" print('小学没读好?除数能为0吗?')\n",
"except _____________:\n",
" print('请使用浮点数,斜边必须大于直角边')\n",
"__________:\n",
" print(\"结束\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

Loading…
Cancel
Save