python3.9.5超浓缩教程

文章目录

  • 前言
  • 安装
    • 环境
    • 下载python
    • 安装python
    • 测试python
    • 问题:在命令行中输入`python`并回车,会弹出应用商店
    • 问题:打开安装包没有`install now`,只有`update……`
  • 写个hello world
    • 创建源代码文件
    • 使用IDLE编辑器打开源文件
    • 写个hello world
    • 问题:文本文档改名后图标没变,右击也没有`edit with idle`
  • 给hello world加注释
    • 如何输入注释
  • 代码块
    • 用缩进格式来表示代码块
    • 问题:用缩进调整格式,以增加代码可读性,但报错
  • 使用“变量”
    • 示例
  • 使用“方法”
    • 语法
    • 示例
  • 使用“属性”
    • 语法
    • 示例
  • 常用内置数据类型:序列——字符串
    • 如何输入字符串
    • 两个字符串合并
    • 重复输入相同的字符串的简便方法
    • 获取字符串中指定位置的字符
    • 复制字符串中编号连续的部分:切片操作
    • 问题:跨行连续输入中的反斜杠不能删除换行
  • 常用内置数据类型:数字
    • 整数`int`
    • 浮点数`float`
      • 查看浮点数的详细限制
    • 复数`complex`
    • 布尔`bool`
  • 内置数据类型:序列——列表
    • 如何输入列表
    • 获取列表中指定位置的值
    • 复制或修改列表中编号连续的部分:切片操作
    • 两个列表合并
    • 修改指定编号的元素
    • 在列表结尾添加新元素
  • 内置数据类型:字典
    • 如何输入字典
  • 比较运算
    • 数学比较运算符 >、<、==、!=、>=、<= 的使用
    • 对象标志号的使用:a 就是 b
    • 否定的对象标志号的使用:a 不是 b
  • 布尔运算
    • 示例
  • 算术运算
    • 示例
  • 赋值运算
    • 等于号
    • 其他赋值符号
  • 流程控制工具:`if`
    • `if`语法
    • 示例:最简单的`if`
    • 示例:复杂一点的`if`
    • 示例:最复杂的`if`
  • 流程控制工具:`for`
    • `for`语法
    • 示例:最简单的`for`
    • 示例:中途退出的`for`和成功遍历结束有反馈的`for`
    • 示例:跳过当前元素的`for`
    • 问题:在`if`中使用`break`时,遍历每个元素都会执行`for`的`else`
  • 流程控制工具:`while`
    • `while`语法
    • 示例:最简单的`while`
    • 示例:中途退出的`while`
    • 示例:跳过当前代码块的`while`
    • 示例:成功执行结束有反馈的`while`
  • `pass`语句
    • 示例
  • 函数的定义和调用
    • 写一个没有参数、没有返回值的函数
    • 写一个有参数的函数
    • 写一个有参数、有返回值的函数
    • 写一个有默认值参数的函数
    • 写一个可以有任意数量个参数的函数:参数列表
    • 写一个能接受键值对参数的函数:键值对参数列表
    • 改变参数值传递给函数的方式:特殊参数
      • 如何指定传递方式
    • 问题:运行时报错“NameError: name '函数名' is not defined”
  • 模块
    • 示例
  • 句法错误
    • 示例
  • 异常
    • 示例
    • 已知的异常
    • 处理异常:`try`
      • 语法
      • 示例:一个最简单的try
      • 示例:使每个except只匹配指定的异常
      • 示例:不带异常名的except将匹配所有异常
      • 示例:获取异常的详细说明
      • 示例:else和finally
      • 示例:异常没有被任何except匹配
    • 写一个有属性、有方法的类
    • 写一个创建实例后,会自动执行特定代码的类
    • 利用其他的类的方法和属性来创建一个类:继承
  • 标准库
    • 多种操作系统接口:os 模块
    • Unix 风格路径名模式扩展:glob 模块
    • 系统相关的参数和函数:sys 模块
    • 正则表达式操作:re 模块
    • 数学函数:math 模块
    • 生成伪随机数:random 模块
    • 数学统计函数:statistics 模块
    • 用于打开 URL 的可扩展库:urllib.request 模块
    • SMTP协议客户端:smtplib 模块
    • 基本的日期和时间类型:datetime 模块
    • 数据压缩:zlib、gzip、bz2、lzma、zipfile、tarfile 模块
    • 测量小代码片段的执行时间:timeit 模块
    • 测试交互性的Python示例:doctest 模块
    • 基于线程的并行:threading 模块
    • 另一种 repr() 实现:reprlib 模块
    • 示例
  • 电脑中的零和一,如何转换成我们的看得懂的信息
    • 数字
    • 文字
    • 媒体
  • 编码风格

若有 bug 或疑问,就在评论区告诉我吧 ฅ( ̳• ◡ • ̳)ฅ♪

前言

目录太长,又不能折叠,我自己看得都头疼。

每个章节中,常用知识我靠前写,难得一用的就靠后写,大家根据需要学。

安装

环境

  • 操作系统:windows 10 64位 专业版
  • python版本:3.9.5 64位
  • 代码编辑器:IDLE 3.9(这是官方的python安装包自带的编辑器)

下载python

可在官网寻找适合自己系统的安装包,官网地址:https://www.python.org

windows 64位的安装包下载地址:

  • 官网下载地址:https://www.python.org/ftp/python/3.9.5/python-3.9.5-amd64.exe
  • 百度网盘下载:链接:https://pan.baidu.com/s/1H8YYJFIxn-JWCsWVJxLhUg提取码:gnq7

安装python

  • 下载的安装包名称为python-3.9.5-amd64,打开它。
  • 勾选add python 3.9 to path,并点install now
  • 在结束界面点disable path length limit。(它能使windows支持更长的完整文件名。)

测试python

按快捷键WIN+R->会在屏幕左下角打开运行窗口->输入cmd->点确定->会打开命令行窗口->输入python,并按回车。若效果如下,则安装成功;

Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

问题:在命令行中输入python并回车,会弹出应用商店

在命令行中输入python并回车,会弹出应用商店,并且开始菜单中有python 3.9 (64bit)

原因是在安装界面没有勾选add python 3.9 to path。卸载重装,勾选该项即可解决。

问题:打开安装包没有install now,只有update……

说明电脑中已经有python了,点update……即可,会将python更新为3.9.5版本。

结束界面若有disable path length limit,也要点。

写个hello world

创建源代码文件

在桌面新建一个文本文档,改名为a.py,文件的图标会从文本文档变为python源文件的图标。

好了,一个名为a的python源文件就创建好了。

使用IDLE编辑器打开源文件

右击a.py文件->点edit with idle->点edit with idle 3.9(64 bit),会打开IDLE->在打开的IDLE中就可以编辑此源文件了。

写个hello world

print()功能可以在屏幕上显示内容,并加一个换行,只要把内容放在它的括号中即可,内容需要用双引号括起来(也有不用双引号的方法)。

显示一行hello world:

print("hello world!")

代码输入好之后,点工具栏的“Run”->“Run Module”,或直接按“F5”,就能使用IDLE自带的shell工具来运行代码了,输出效果如下:(系统运行前会检查代码,会在有错误的位置显示红色,并弹出写有错误信息的消息框;对于在运行过程中才能发现的错误,错误信息会显示在shell工具中)

Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
====================== RESTART: C:\Users\zzs\Desktop\a.py ======================
hello world!
>>> 

显示两行hello world:

print("hello world!");print("hello world!")

Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
====================== RESTART: C:\Users\zzs\Desktop\a.py ======================
hello world!
hello world!
>>> 

在“====”行和“>>>”行之间的内容,就是我们代码输出的内容。以后我只截取代码输出的内容。

两个测试代码都是有两行,第二行是空行。加空行的原因:用换行来表示一句代码结束,而分号只用于在一行需要写多条语句时,要用分号将两个语句隔开。

虽然对于最后一行的语句不加换行也不要紧,但出于良好的习惯,和严格一致的语法,建议加上换行。

问题:文本文档改名后图标没变,右击也没有edit with idle

这是没有改后缀名导致的。如果电脑没有设置过要显示后缀名,那是无法修改后缀名的。设置方法:打开“此电脑”->左上角“文件”->更改文件架和搜索选项->查看->高级设置->取消勾选“影藏已知文件类型的扩展名”->应用->确定。

设置完成后文件名会从新建文本文档变成新建文本文档.txt,此时再将新建文本文档.txt改为a.py即可。

给hello world加注释

注释就是给阅读代码的人看的,怕别人看不懂自己的代码或自己防止忘记这段代码的用处,而写的一些说明和解释。

注释虽然和代码一起写在源文件中,但注释不属于代码,注释不会被运行,也不会在运行时被显示出来。

如何输入注释

# 以#开头的是单行注释。
'''
这是多行注释,前后用三个单引号括起来
可以连续写多行内容
'''
"""
这也是多行注释,前后用三个双引号括起来
"""
print("hello world!") # 单行注释也可以跟在语句后面。

hello world!

代码块

将多条连续的语句指定为一个整体,使之被系统识别为一条语句。

有些地方只能执行一条语句,此时就可以写一个代码块,使之能够执行多条语句。

用缩进格式来表示代码块

可以使用制表符tab或空格来缩进。根据python官方建议,请使用4个空格来表示一次缩进,因为有些电脑不支持tab

下面的示例中,用{-->}表示缩进。一个{-->}表示一次缩进,{-->}{-->}则表示两次缩进。

代码块 1
代码块 1
{-->}代码块 2:嵌套在代码块 1中,是1的一部分。
{-->}代码块 2:嵌套在代码块 1中,是1的一部分。
{-->}{-->}代码块 3:嵌套在代码块 2中,是2的一部分。
{-->}{-->}代码块 3:嵌套在代码块 2中,是2的一部分。
{-->}代码块 2:嵌套在代码块 1中,是1的一部分。
{-->}代码块 2:嵌套在代码块 1中,是1的一部分。
{-->}{-->}代码块 4:嵌套在代码块2中,是2的一部分。和代码块 3没关系。
{-->}{-->}代码块 4:嵌套在代码块2中,是2的一部分。和代码块 3没关系。
代码块 1
代码块 1

问题:用缩进调整格式,以增加代码可读性,但报错

缩进是语法的一部分,所以不能随意使用,即不能仅为了调整格式而使用缩进。例如,下面的代码将会报错,报错位置是第二行,报错内容为:unexpected indent。

print("代码块1")
	print("缩进,试图将它变为代码块2")
print("代码块1")

把第二行的缩进去掉就能正常运行:

print("代码块1")
print("缩进,试图将它变为代码块2")
print("代码块1")

代码块1
缩进,试图将它变为代码块2
代码块1

使用“变量”

电脑中的数据保存在一个个连续编号的存储介质中,通过编号就能找到需要的数据,比如,编号0xE3D5443C2130035960176这种编号被称为地址,储存在内存中时,就称为内存地址,储存在硬盘中时,就称为硬盘地址。

因为地址太难记,所以允许我们给它起个名字,名字可以只是一个字母,也可以是一长串字母加数字,甚至是汉字。大家不要用汉字,因为编码问题,所以可能会出错,而且IDLE不能帮你找到出错位置。

示例

# 等于号表示赋值操作,其让等于号左边的变量来表示右边的数据所在的地址。
# 具体存放在哪个地址中?这无需我们操心,系统会自动挑选,我们使用为它起的名字即可。
# 虽然变量分不同的类型(比如存数字的变量类型,存文字的变量类型),但都能自动转变,或有相应的转变功能给我们选择使用。
a=b=3 # 从右到左,变量依次表示为3所在的地址。
# 因为系统自动优化,有些情况a、b的地址相同,有些情况会复制成两个3,存在两个地址中,a、b的地址就不同,但两个地址中储存的数据都是3。
print(a)
print(b)
a,b=2-1,2/2 # 用该方式赋值不同的数据所在的地址。
print(a) # a是整数类型
print(b) # 做除法时,会自动变为浮点数(小数)类型。
del a # 删除变量。当没有任何变量表示某个地址时,该地址将会还给系统等待其他需要保存的数据。
print(a) # 被删除的变量,除非再次赋值,否则无法使用,因为它被删除后就不代表任何地址。

3
3
1
1.0
Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\a.py", line 11, in 
    print(a) # 被删除的变量,除非再次赋值,否则无法使用,因为它被删除后就不代表任何存储介质了。
NameError: name 'a' is not defined

使用“方法”

“方法”就是功能,必须是针对一个变量来使用某个方法,意思是给此对象使用某个功能。比如print(),有时候也被称之为print()方法,它的功能是在屏幕上显示内容,当它用作方法时,也要遵从方法的语法。

这些可以使用方法的变量,其保存的数据统一被称为对象,我们在表述时为了方便,就直接说对象,而不说变量。

语法

在对象后面写个小数点,再写方法名称加括号,使用方法时需要的内容,就写在括号中。

对象名称.方法名称()

示例

bit_length()方法:对象转换为二进制后,有多少位数字。该方法使用时不需要给它内容,所以括号里不用填东西。

a=233 # 二进制为 8 位:11101001
c=a.bit_length() # 对 a 使用 bit_length() 功能,得到此功能运行的结果,保存在 c 中。
print(c)

8

使用“属性”

属性就是变量的内在数据,一个变量可能有多个属性,想要获取或改变它,就要用相应的属性名称。

和“方法”一样的原因,这些变量被称为对象。

语法

在变量后面写个小数点,再写属性名称。

对象名称.属性名称

示例

import datetime
a=datetime.date(2021,2,3) # 在 a 中储存日期:2021年1月3日
print(a) # 直接使用 a ,是不会出现内部数据的。
b=a.min # a 有属性,min表示能储存的最小日期。
print(b)
a.min=a # 用等于号来修改属性的数据,但有些属性是禁止修改,比如此处的min就不能修改,修改它就会报错。

2021-02-03
0001-01-01
Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\a.py", line 6, in 
    a.min=a
AttributeError: 'datetime.date' object attribute 'min' is read-only

常用内置数据类型:序列——字符串

一个字符串,就是一堆文字。

组成字符串的每一个文字,都称作字符。

当字符串中只有一个文字时,我们既可以称为字符串,也可以称为字符。

如何输入字符串

# 用单引号或双引号标注。
a='字符串单引号' 
print(a)
a="字符串双引号"
print(a)
# 反斜杠表示特殊含义的内容(转义),如\r\n表示回车换行。
a="转义第一行\r\n第二行" 
print(a)
# 前面加 r,可取消反斜杠的转义功能。
a=r"转义第一行\r\n第二行" 
print(a)
# 三个单引号或双引号可实现跨行连续输入。
a="""第一行
第二行"""
print(a)
# 行尾添加反斜杠,可去除回车换行。
# 在空行使用反斜杠,即为删除改行,如下面的第一行。
a="""\
第二行
第三行\
第四行
"""
print(a)

字符串单引号
字符串双引号
转义第一行
第二行
转义第一行\r\n第二行
第一行
第二行
第二行
第三行第四行

两个字符串合并

使用加号连接即可。

a='111'
b='aaa'
c=a+b
print(c)

111aaa

还有另一种方法,不过只能在写代码的过程中,输入字符串时使用,一般用于把一行长字符串分开输入。

输入方法:两个字符串紧挨着写,并放在括号里(不换行的话,可以不写括号)。

a='Py''thon'
print(a)
b=('abcdefg'
'hijklmn'
'opqrstuvwxyz')
print(b)
'''
# 下面的写法是错误的,因为必须是输入字符串,不能使用变量。
# 若要使用变量,那就用加号连接的方式来合并。
c='aabbcc'b 
print(c)
'''

Python
abcdefghijklmnopqrstuvwxyz

重复输入相同的字符串的简便方法

*表示重复,再加上重复次数即可。

a='111'*3
b=3*'aaa'
print(a)
print(b)

111111111
aaaaaaaaa

获取字符串中指定位置的字符

字符串中的每个字符都有编号,而且每个字符都有两个编号。(编号方式和“内置数据类型:序列——列表”相同)

第1种编号方式是从左往右,最左边是从0开始;第2种编号方式是从右往左,最右边是从-1开始。

第几个值 1 2 3 …… n-2 n-1 n
第1种编号方式 0 1 2 3 4 …… n-1
第2种编号方式 -n -(n-1) …… -4 -3 -2 -1

示例:

字符串’135abc’ 1 3 5 a b c
第1种编号方式 0 1 2 3 4 5
第2种编号方式 -6 -5 -4 -3 -2 -1

使用编号,获取第2个值:

a='135abc'
b=a[1] # 编号放在紧跟着字符串变量的中括号中即可。
print(b)
b=a[-5]
print(b)

3
3

注:因为-0 和 0 一样,因此,负数索引从 -1 开始,而不是-0。

如果编号过大或过小,超出了字符串的范围,则会报错。比如字符串’135abc’,第1中编号方式的最大值是5,第2种编号方式的最小值是-6,编号只能在范围[-6,5]之间,如果超出了范围,使用编号8或-7,则会报错:

a='135abc'
b=a[8]

Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\a.py", line 2, in 
    b=a[8]
IndexError: string index out of range

复制字符串中编号连续的部分:切片操作

通过指定起始的编号和结束的编号,来表示字符串中的编号连续的一部分。

用数学中的范围表示,即[ 起始编号, 结束编号 ),即包含起始编号的字符,但不包含结束编号的字符。

跟获取单个字符类似,开始编号和结束编号用冒号隔开,并将它们包含在中括号中。

# 第1种编号方式
a='135abc'
print(a[1:1]) # 当起始编号和结束编号相同时,将不包含任何字符。
print(a[1:3])
print(a[1:]) # 不指定结束编号,将一直复制到最后一个字符。
print(a[:3]) # 不指定起始编号,将从第一个字符开始复制
print(a[:])
print(a[1:100]) #当结束编号超过范围,将复制到最后一个字符停止。
print(a[50:100]) #当起始编号超过范围,将不包含任何字符。


35
35abc
135
135abc
35abc

# 第2种编号方式
a='135abc'
print(a[-5:-5])
print(a[-5:-3])
print(a[-5:])
print(a[:-3])
print(a[:])

35
35abc
135
135abc

两种编号方式混用,会自动转换成相同的编号方式,再进行切片操作:

a='135abc'
print(a[1:-2])

35a

问题:跨行连续输入中的反斜杠不能删除换行

反斜杠被显示了出来,并没有删除换行。因为反斜杠后面可能有个空格,删去空格,使之在行的末尾即可。

常用内置数据类型:数字

包含整数、浮点数、复数、布尔。

整数int

就是数学中的整数,……、-3、-2、-1、0、1、2、3……这些就是整数。

整数的的大小没有限制,即无论多大的正整数,还是多小的负整数,都可以使用。

a=999999999999999999999999999999999999999999
b=-888888888888888888888888888888888888888888
c=a-b
print(c)

1888888888888888888888888888888888888888887

浮点数float

浮点表示小数,比如3.21.00.123。浮点数以指数表示法(科学计数法)进行储存,即把小数点移到最左边。并记录移动的位数。比如,数字15628.334保存为156283346,科学计数法表示为0.15628334*10^6,也就是15628.334

浮点数有大小限制,不同电脑和操作系统的限制不同,当小数长度超过容量时,会进行舍入(取近似值):

x=123.9999999
print(x)
x=123.9999999999999999999999999999999
print(x)

123.9999999
124.0

查看浮点数的详细限制

sys.float_info的属性中可以查看自己电脑的浮点数限制,代码如下:(属性可以理解为是保存的数据的名字,类似变量)

import sys
print('sys.float_info.epsilon:')
print(sys.float_info.epsilon)
print('sys.float_info.dig:')
print(sys.float_info.dig)
print('sys.float_info.mant_dig:')
print(sys.float_info.mant_dig)
print('sys.float_info.max:')
print(sys.float_info.max)
print('sys.float_info.max_exp:')
print(sys.float_info.max_exp)
print('sys.float_info.max_10_exp:')
print(sys.float_info.max_10_exp)
print('sys.float_info.min:')
print(sys.float_info.min)
print('sys.float_info.min_exp:')
print(sys.float_info.min_exp)
print('sys.float_info.min_10_exp:')
print(sys.float_info.min_10_exp)
print('sys.float_info.radix:')
print(sys.float_info.radix)
print('sys.float_info.rounds:')
print(sys.float_info.rounds)

sys.float_info.epsilon:
2.220446049250313e-16
sys.float_info.dig:
15
sys.float_info.mant_dig:
53
sys.float_info.max:
1.7976931348623157e+308
sys.float_info.max_exp:
1024
sys.float_info.max_10_exp:
308
sys.float_info.max:
2.2250738585072014e-308
sys.float_info.min_exp:
-1021
sys.float_info.min_10_exp:
-307
sys.float_info.radix:
2
sys.float_info.rounds:
1

sys.float_info中各个数值的解释:

属性 说明
epsilon epsilon=(大于 1.0 的最小值) - 1.0。即两个浮点数之间的最小间隔(浮点数不是无穷的,也就意味着不是连续的,两个数之间必然有空挡,也就是间隔)。
dig 浮点数最多可以表示多少位数字(十进制),将会删掉过多的数字,并舍入。有些小数未超过该位数,也进行了舍入,因为计算机用的时而仅是,有些十进制的有限小时,用二进制表示就变成了无限小数,所以被删掉了部分。
mant_dig 浮点数精度:radix 基数下的浮点数有效位数。
max 浮点数可以真实表示的最大数字。
max_exp 在计算机中的二进制小数,其小数点可以向右移动的最大位数。
max_10_exp 十进制小数,其小数向右移动的最大位数。
min 可表示的最小正的浮点数。
min_exp 在计算机中的二进制小数,其小数点可以向左移动的最大位数。
min_10_exp 十进制小数,其小数向左移动的最大位数。
radix 指数表示法中采用的基数,默认为2。我们日常中用科学计数法,基数时10,因为我们用的时十进制,而计算机中用的时二进制,用2为基数才能正确地移动小数点,所以此处为2。
rounds 时一个整数值,不同的数值代表不同的舍入方式:-1不确定;0向零靠近;1就近取值;2向正无穷大靠近;3向负无穷大靠近

虽然介绍很多,但我们只要理解了最大值max,最小值min,最小间隔epsilon,就能理解浮点数了。

复数complex

复数就是数学中所说的由实部和虚部构成的数,数字后面加Jj则为虚部,比如3+2j50-7j,其中350是实部,27是虚部。

布尔bool

布尔用于表示逻辑值,即只能表示两个值,一个是True(真、正确),另一个是False(假、错误)。

一般用于计算判断语句,比如,两个数是否相等,如果相等,计算结果就是True,否则结果是False

内置数据类型:序列——列表

将多个数据保存在一起,组成的新数据,就叫列表。组成列表中的每个数据,都称为元素。

列表中可以存放字符串、数字,甚至是列表。

如何输入列表

用中括号包含所有元素,两个元素之间用都好隔开,再用等于号赋值给变量。

a=[1,3,5,'a','b','c',['A','B']]
print(a)

[1, 3, 5, 'a', 'b', 'c']

获取列表中指定位置的值

列表中的每个值都有编号,而且每个值都有两个编号。(编号方式和“内置数据类型:序列——字符串”相同)

第1种编号方式是从左往右,最左边是从0开始;第2种编号方式是从右往左,最右边是从-1开始。

第几个值 1 2 3 …… n-2 n-1 n
第1种编号方式 0 1 2 3 4 …… n-1
第2种编号方式 -n -(n-1) …… -4 -3 -2 -1

示例:

列表[1,3,5,‘a’,‘b’,‘c’] 1 3 5 ‘a’ ‘b’ ‘c’
第1种编号方式 0 1 2 3 4 5
第2种编号方式 -6 -5 -4 -3 -2 -1

使用编号,获取第2个值:

a=[1,3,5,'a','b','c']
b=a[1] # 编号放在紧跟着列表变量的中括号中即可。
print(b)
b=a[-5]
print(b)

3
3

注:因为-0 和 0 一样,因此,负数索引从 -1 开始,而不是-0。

如果编号过大或过小,超出了列表的范围,则会报错。比如列表[1,3,5,‘a’,‘b’,‘c’],第1种编号方式的最大值是5,第2种编号方式的最小值是-6,编号只能在范围[-6,5]之间,如果超出了范围,使用编号8或-7,则会报错:

a=[1,3,5,'a','b','c']
b=a[8]
Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\a.py", line 2, in 
    b=a[8]
IndexError: list index out of range

复制或修改列表中编号连续的部分:切片操作

通过指定起始的编号和结束的编号,来表示列表中的编号连续的一部分。

用数学中的范围表示,即 [ 起始编号, 结束编号 ),即包含起始编号的元素,但不包含结束编号的元素。

跟获取单个元素类似,开始编号和结束编号用冒号隔开,并将它们包含在中括号中。

# 第1种编号方式
a=[1,3,5,'a','b','c']
print(a[1:1]) # 当起始编号和结束编号相同时,将不包含任何元素。
print(a[1:3])
print(a[1:]) # 不指定结束编号,将一直复制到最后一个元素。
print(a[:3]) # 不指定起始编号,将从第一个元素考试复制
print(a[:])
print(a[1:100]) #当结束编号超过范围,将复制到最后一个元素停止。
print(a[50:100]) #当起始编号超过范围,将不包含任何元素。
a[1:4]=['A','B'] # 将列表中编号为 1、2、3 的这段元素,替换为['A','B']
print(a)

[]
[3, 5]
[3, 5, 'a', 'b', 'c']
[1, 3, 5]
[1, 3, 5, 'a', 'b', 'c']
[3, 5, 'a', 'b', 'c']
[]
[1, 'A', 'B', 'b', 'c']
# 第2种编号方式
a=[1, 3 ,5,'a','b','c']
print(a[-5:-5])
print(a[-5:-3])
print(a[-5:])
print(a[:-3])
print(a[:])

[]
[3, 5]
[3, 5, 'a', 'b', 'c']
[1, 3, 5]
[1, 3, 5, 'a', 'b', 'c']

两种编号方式混用,会自动转换成相同的编号方式,再进行切片操作:

a=[1,3,5,'a','b','c']
print(a[1:-2])

[3, 5, 'a']

两个列表合并

使用加号连接即可。

a=[1, 3 ,5,'a','b','c']
b=[4,5,6,'d']
print(a+b)

[1, 3, 5, 'a', 'b', 'c', 4, 5, 6, 'd']

修改指定编号的元素

用等于号给指定编号的元素赋值即可。

a=[1, 3 ,5,'a','b','c']
a[2]='d'
print(a)

[1, 3, 'd', 'a', 'b', 'c']

在列表结尾添加新元素

这里有个新知识——“方法”。

使用列表的append()方法,可以在列表结尾添加新元素。使用方式:在变量后面写个小数点,再写方法名称加括号,使用方法时需要的内容,就写在括号中。

a=[1, 3 ,5,'a','b','c']
a.append('d')
print(a)

[1, 3, 5, 'a', 'b', 'c', 'd']

内置数据类型:字典

字典的主要用途是通过关键字存储、提取值。可以理解为列表的一种,不过其中每个元素都可以起个名字。

如何输入字典

a={
     'name':'张三','age':16}
print(a['name'])
print(a['age'])

张三
16

比较运算

比较运算就数学中的比大小,让系统判断是否正确,比如,执行代码“a大于b”,若a确实大于b,则运算结果True,否则为False。

运算时使用大于号、小于号、等于号等等来表示执行哪种比较:(它们称为比较运算符、或关系运算符)

符号 含义
> 大于号
< 小于号
== 等于号
!= 不等于号
>= 大于等于号
<= 小于等于号
is 对象标志
is not 否定的对象

数学比较运算符 >、<、==、!=、>=、<= 的使用

a,b=3,4
print('大于号的使用:a大于b')
c=a>b # c 保存布尔运算的结果
print(c)
print('---------------------')
print('小于号的使用:a小于b')
c=a<b
print(c)
print('---------------------')
print('等于号的使用:a等于b')
c=a==b
print(c)
print('---------------------')
print('不等于号的使用:a不等于b')
c=a!=b
print(c)
print('---------------------')
print('大于等于号的使用:a大于等于b')
c=a>=b
print(c)
print('---------------------')
print('小于等于号的使用:a小于等于b')
c=a<=b
print(c)

大于号的使用:a大于b
False
---------------------
小于号的使用:a小于b
True
---------------------
等于号的使用:a等于b
False
---------------------
不等于号的使用:a不等于b
True
---------------------
大于等于号的使用:a大于等于b
False
---------------------
小于等于号的使用:a小于等于b
True

对象标志号的使用:a 就是 b

is会同时比较存储介质的地址和数据,两个都相同才会返回True

a=3
b=4
c=a is b # c 保存布尔运算的结果
print(c)
print(id(a),id(b)) # 这样可以显示a、b的在存储介质中的编号。
a=3
b=a
c=a is b # c 保存布尔运算的结果
print(c)
print(id(a),id(b)) # 这样可以显示a、b的在存储介质中的编号。

False
2402483267952 2402483267984
True
2402483267952 2402483267952

否定的对象标志号的使用:a 不是 b

is做相同的事情,不过结果相反。

a=3
b=4
c=a is not b # c 保存布尔运算的结果
print(c)
print(id(a),id(b)) # 这样可以显示a、b表示的地址。
a=3
b=a
c=a is not b # c 保存布尔运算的结果
print(c)
print(id(a),id(b)) # 这样可以显示a、b表示的地址。

True
2130035960176 2130035960208
False
2130035960176 2130035960176

布尔运算

布尔运算一般用于:有多个逻辑值时,如何对待它们。

比如,有两个逻辑值,需要当它们都为True时,才能视为True,否则为False。这种对待它们的方式,就称为布尔运算。

布尔运算有以下几种,分别用不同的符号来表示:

符号 含义
and 当两个都为True时,则返回True,否则返回False
or 两个中只要有True,则返回True,否则返回False
not 将一个逻辑值反过来,若其为True,则返回False,否则返回True

示例

以下是所有情况的的计算结果:

print('and 运算')
print(True and True)
print(False and False)
print(True and False)
print(False and True)
print('or 运算')
print(True or True)
print(False or False)
print(True or False)
print(False or True)
print('not 运算')
print(not True)
print(not False)

and 运算
True
False
False
False
or 运算
True
False
True
True
not 运算
False
True

实际中使用的例子:

if 3<4 and 6<5:
    print('True')
else:
    print('False')

False

算术运算

算数运算就是数学中的加、减、乘、除等等这些运算。

加、减、乘、除等等,用以下的符号表示:(它们称为算术运算符)

符号 含义
+
-
*
/
**
% 取模
// 整除

示例

a=8
b=3
print('加法:a+b')
print(a+b)
print('减法:a-b')
print(a-b)
print('乘法:a*b')
print(a*b)
print('除法:a/b(小数过多时会取近似值)')
print(a/b)
print('幂运算:a**b')
print(a**b)
print('取模运算:a%b(计算除法的余数)')
print(a%b)
print('整除运算:a//b(除法运算后,结果总是向负无穷的方向舍入)')
print(a//b)

加法:a+b
11
减法:a-b
5
乘法:a*b
24
除法:a/b(小数过多时会取近似值)
2.6666666666666665
幂运算:a**b
512
取模运算:a%b(计算除法的余数)
2
整除运算:a//b(除法运算后,结果总是向负无穷的方向舍入)
2

赋值运算

赋值运算使用的符号,主要就是等于号,其它的都是为了写代码时能偷懒少打几个字而发明的。

等于号

等于号的作用,就是把右边的数据复制到左边:

a=3 # 右边的 3,复制到了左边的 a 里面
b=a # 左边的 a(上一句已经把 a 已经变成了 3),复制到了右边的 b
print(b) # 上一句 b 也被变成了3

3

其他赋值符号

海象运算符偷懒的效果最明显,其它的一般般。

符号 含义 写法示例 不偷懒的写法
:= 海象运算符 print(c:=a+b) a=a+b;print(c)
+= 加法赋值运算符 a+=b a=a+b
-= 减法赋值运算符 a-=b a=a-b
*= 乘法赋值运算符 a*=b a=a*b
/= 除法赋值运算符 a/=b a=a/b
** 幂赋值运算符 a**=b a=a**b
% 取模赋值运算符 a%=b a=a%b
//= 取整除赋值运算符 a//=b a=a//b

流程控制工具:if

使用if时,需要给它一个布尔值,当值为True,则执行指定的代码块,否则执行指定的另一个代码块或什么都不执行。

if语法

最简单的if

if [布尔值]:
	[仅布尔值为True时才执行的代码块]

复杂一点的if

if [布尔值]:
	[仅布尔值为True时才执行的代码块]
else:
	[仅布尔值为false时才执行的代码块]

最复杂的if

if [布尔值1]:
	[仅布尔值1为True时才执行的代码块]
elif [布尔值2]:
	[仅布尔值2为True时才执行的代码块]
……
elif [布尔值n]:
	[仅布尔值n为True时才执行的代码块]
else:
	[仅布尔值1、2、……n都不为True时才执行的代码块]

示例:最简单的if

x=False
if x:
    print("1")
x=True
if x:
    print("2")

2

示例:复杂一点的if

x=False
if x:
    print("x 是 True")
else:
    print("x 不是 True")

x 不是 True

示例:最复杂的if

x=False
y=False
if x:
    print("x 是 True")
elif y:
    print("y 是 True")
else:
    print("y 和 x 都不是 True")

y 和 x 都不是 True

流程控制工具:for

for可以依次历遍列表中的元素。

for语法

最简单的for

for [存放当前遍历到的元素] in [需要遍历的列表]
	[要执行的代码块,可使用当前遍历到的元素]

中途退出的for

for [存放当前遍历到的元素] in [需要遍历的列表]
	[要执行的代码块,可使用当前遍历到的元素]
	[break,执行到该关键字则退出for]

未执行break时会有反馈的for

for [存放当前遍历到的元素] in [需要遍历的列表]
	[要执行的代码块,可使用当前遍历到的元素]
	else:
		[仅在成功遍历结束后,才会执行的代码块]

跳过当前元素的for

for [存放当前遍历到的元素] in [需要遍历的列表]
	[要执行的代码块,可使用当前遍历到的元素]
	[continue,跳过当前元素]
	else:
		[仅在成功遍历结束后,才会执行的代码块]

示例:最简单的for

words = [1, 2, 'a','b']
for i in words:
    print(i)
    
1
2
a
b

示例:中途退出的for和成功遍历结束有反馈的for

words = [1, 2, 'a','b']
for i in words:
    print(i)
    if i=='a': # 遍历到 a 时退出,中途退出的for,即未能成功遍历结束,所以不会执行反馈。
        break
else:
    print('完成')

1
2
a

目前,能让for无法执行下去的方法,只有使用break,所以,只要不执行break,就能成功完成for

words = [1, 2, 'a','b']
for i in words:
    print(i)
    if i=='c': # 遍历到 c 时退出,但因为列表中没有 c,所以不会执行退出,会遍历完成。
        break
else:
    print('完成')

1
2
a
b
完成

示例:跳过当前元素的for

words = [1, 2, 'a','b']
for i in words:
    if i=='a':
        print('跳过')
        continue
    print(i)
else:
    print('完成')

1
2
跳过
b
完成

问题:在if中使用break时,遍历每个元素都会执行forelse

这是因为else被识别为了if的一部分,而不是for的一部分,要重新检查缩进,for和其else的缩进应当一致:

words = [1, 2, 'a','b']
for i in words:
    print(i)
    if i=='c':
        break
    else:
        print('完成')

1
完成
2
完成
a
完成
b
完成

调整为正确的缩进,问题即可解决:

words = [1, 2, 'a','b']
for i in words:
    print(i)
    if i=='c':
        break
else:
    print('完成')

1
2
a
b
完成

流程控制工具:while

使用while时,需要给它一个布尔值。while会先判断布尔值,若为True,则执行指定的代码块;然后再次判断布尔值,若依旧为True,则再次执行指定的代码块;……如此往复,直到为False,才不会不再执行这指定的代码块。

while语法

最简单的while

while [布尔值]:
    [仅布尔值为True时,才代码块]

中途退出的while

while [布尔值]:
    [仅布尔值为True时,才代码块]
    [break]

跳过当前代码块的while。使while立即停止执行代码块,并回到判断布尔值的步骤:

while [布尔值]:
    [仅布尔值为True时,才代码块]
    [continue]

成功执行结束有反馈的while。在判断布尔值步骤,布尔值为False,则视为while成功执行结束,成功执行结束后会执行一次else的代码块:

while [布尔值]:
    [仅布尔值为True时,才执行的代码块]
else:
    [仅布尔值为False时,才执行的代码块]

示例:最简单的while

先判断布尔值a<=31<=3),为True,则执行代码块;
然后再次判断布尔值a<=32<=3),为True,则执行代码块;
然后再次判断布尔值a<=33<=3),为True,则执行代码块;
然后再次判断布尔值a<=34<=3),为False,则停止执行代码块。

a=1
while a<=3:
    print(a)
    a=a+1

1
2
3

示例:中途退出的while

a等于2时,使用break,立即退出当前的while

a=1
while a<=3:
    if a==2:
        break
    print(a)
    a=a+1

1

示例:跳过当前代码块的while

a等于2时,使用continue,代码块中后面部分将不会执行,而是回到判断布尔值的步骤。

这个代码中,如果不在if使用a=a+1语句,则这个while会永远执行下去。因为当a等于2时,会不执行最后一句的a=a+1语句,所以a会永远是2,布尔值也就永远是True,导致while永远不会停止。

a=1
while a<=3:
    if a==2:
        a=a+1
        continue
    print(a)
    a=a+1

1
3

示例:成功执行结束有反馈的while

只要在判断布尔值步骤,布尔值为False,则视为while成功执行结束。

a=1
while a<=3:
    if a==2:
        a=a+1
        continue
    print(a)
    a=a+1
else:
    print('成功完成')

1
3
成功完成

pass语句

书写方式:

pass

该语句不执行任何操作。当语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。

示例

if 3<2:
    pass
    # 不会出现True的情况,所以这里不用写代码。
    # 但语法上应该在这里有代码,此时我们就可以用 pass。
else:
    print('false')

false

函数的定义和调用

定义函数,意思就是创建函数。

调用函数就是使用函数,比如使用print()来输出hello world,就是调用print()函数。

函数就是一段单独的程序,有些函数运行时需要给它一些数据,有些函数还会它给我们一些数据(函数给我们的数据称作返回值)。比如,用print函数显示信息,我们就要给它需显示的内容,它才能运行。

函数的定义应当写在使用的前面,即先创建,再使用。

写一个没有参数、没有返回值的函数

语法

def 函数的名字()
	[函数的代码块]

示例

创建一个名称为A的函数,函数的功能:输出四句话“我是个:”、“函数”、“我的名字叫:”、“A”。

def A():
    print('我是个:')
    print('函数')
    print('我的名字叫:')
    print('A')
A() # 就像使用print一样,写个函数名,然后加个括号即可。

我是个:
函数
我的名字叫:
A

写一个有参数的函数

参数就是使用函数时,我们写在括号里的内容,比如print(“hello world!”),其中"hello world!"就称为参数。

在称呼上,还有细致的区分,使用函数时,写入括号中的称为实际参数或实参,有实际的数据;函数接受时,写在函数定义中的称为形式参数或形参,没有数据,只有接受数据的参数名)

语法

参数可以有多个,用逗号隔开即可。

def 函数的名字( 参数1, 参数2, ……, 参数n )
	[函数的代码块]

示例

修改函数A,把输出的第二句和第四句改掉,我们给函数什么内容,它就输出什么内容。

# 该函数有两个参数:a、b。此处的a、b称为形参。
def A(a, b): # a和b就像变量一样,就好比执行了a='有参数的函数'、b='有参数的A'
    print('我是个:')
    print(a) #
    print('我的名字叫:')
    print(b)
# 此处传递的参数'有参数的函数'和'有参数的A'称为实参。
A('有参数的函数','有参数的A') # 就像使用print一样,把函数需要的数据写在括号里。

我是个:
有参数的函数
我的名字叫:
有参数的A

写一个有参数、有返回值的函数

有些函数,在执行结束后,会给我们的一些数据,这些数据就称为返回值。

语法

def 函数的名字( 参数1, 参数2, ……, 参数n )
	[函数的代码块]
	[return 要返回的数据]

示例

retrun在返回数据的同时,也退出了函数,即执行retrun后,函数中的其他未执行的语句就不会被执行了。退出的效果和在for中使用break类似。

有了retrun,我们就可以做一个完成加法运算的函数了:

def add(x, y):
    z=x+y # 相加的结果保存在 z 中。
    return z # 返回 z 的数据。
    print('执行return后,就退出了函数,这句不会被执行。')
a=add(3, 5) # add(3, 5)的返回值是8,这句就相当a=8,即把“add(3, 5)”当作一个变量来使用就行。
print(a)

8

当函数没有return时,会自动返回None。(None表示没有数据)

def A():
    pass
print(A())

None

当没有给return数据时,会自动返回None。(None表示没有数据)

def A():
    return
print(A())

None

写一个有默认值参数的函数

使用函数时,函数的每个参数,都需要我们给它数据,不过默认值参数就可以不给。

我们只需要在定义函数时就给参数一个数据,如果使用函数时不给数据,系统就会自动使用定义函数时给的数据。

语法

def 函数的名字( 参数1, 参数2, ……, 参数n, 默认参数1=数据, 默认参数2=数据, ……, 默认参数n=数据 )
	[函数的代码块]
	[return 要返回的数据]

示例

这是个完成加减法运算的函数,默认参数来选择是加法还是减法。

def add(x, y, z='加法', wrong='既不是加法也不是减法'):
    if z=='加法':
        return x+y
    elif z=='减法':
        return x-y
    else:
        return wrong
a=add(3, 5)
print(a)
a=add(3, 5, z='加法') # 给默认值参数数据时,需要用赋值的语法。
print(a)
a=add(3, 5, z='减法')
print(a)
a=add(3, 5, z='法')
print(a)
a=add(3, 5, '加法') # 不用赋值语法时,会像普通参数一样,按顺序分配给默认值参数
print(a)
a=add(3, 5, '法', '啥也不是')
print(a)

8
8
-2
既不是加法也不是减法
8
啥也不是

写一个可以有任意数量个参数的函数:参数列表

有一种参数,叫做“参数列表”,它以序列的形式存放多个参数。只要在参数名称前加一个星号,参数就变成了参数列表。系统在分配参数的时候,先分配名称或位置对应的参数,剩下的全部塞进这个参数列表中。

参数列表有其默认值:空序列。
语法

def 函数的名字( *参数列表名 )
	[函数的代码块]
	[return 要返回的数据])

示例

def A(*a):
    for i in a:
        print(i)
A('abc','233','1a')

abc
233
1a
# 分配参数时,先分配普通参数和默认参数,最后剩下的参数给参数列表。
def A(x,y,*a,z='z'): # 参数列表后面只能是默认参数,不能有普通参数。
    for i in a:
        print(i)
    print(x)
    print(y)
    print(z)
A('111','222','abc','233','1a',z='333')

abc
233
1a
111
222
333

写一个能接受键值对参数的函数:键值对参数列表

前面加星号参数表示参数列表,前面加两个星号的表示键值对的参数列表。

和参数列表相似,键值对参数列表也有其默认值:空序列。

示例

def a(*args, **kwargs):
    print('args:')
    print(args)
    print('kwargs:')
    print(kwargs)
    print('--------------')
a(1,2,3)
a(a=1,b=2,c=3)
a(1,233,'123abc', a=1,b='a',c='123abc')

args:
(1, 2, 3)
kwargs:
{}
--------------
args:
()
kwargs:
{'a': 1, 'b': 2, 'c': 3}
--------------
args:
(1, 233, '123abc')
kwargs:
{'a': 1, 'b': 'a', 'c': '123abc'}
--------------

改变参数值传递给函数的方式:特殊参数

默认情况下,参数可以按位置或显式关键字传递给函数。

按位置

第一个实参给第一个形参,第二个实参给第二个形参……以此类推。

def aa(a,b,c,d): 
    print(a,b,c,d)
aa(1,2,3,4)

1 2 3 4

按显式关键字

根据参数名称指定给某个形参。

def aa(a,b,c,d):
    print(a,b,c,d)
aa(d=1,c=2,b=3,a=4)

4 3 2 1

如何指定传递方式

使用/*来指定:

  • /左边的,只能按位置传递。
  • *右边的,只能按显式关键字传递。
  • 既不在/左边,又不在*右边,则两种传递方式都能用。
  • 没有指定/*,则两种传递方式都能用。
  • 指定传递方式后,若不按照规定传递,将报错。

示例

pos1pos2/左边的,只能按位置传递;
kwd1kwd2*右边的,只能按显式关键字传递;
pos_or_kwd既不在/左边,又不在*右边,则两种传递方式都能用。

def a(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    print(pos1, pos2, pos_or_kwd, kwd1, kwd2)
a(1, 2, pos_or_kwd=3, kwd1=4, kwd2=5)

1 2 3 4 5

改变pos_or_kwd的传递方式:

def a(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    print(pos1, pos2, pos_or_kwd, kwd1, kwd2)
a(1, 2, 3, kwd1=4, kwd2=5)

1 2 3 4 5

pos1使用按显式关键字传递,将报错:positional argument follows keyword argument。

def a(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    print(pos1, pos2, pos_or_kwd, kwd1, kwd2)
a(pos1=1, 2, pos_or_kwd=3, kwd1=4, kwd2=5)

kwd1使用按位置传递,将报错:positional argument follows keyword argument。

def a(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    print(pos1, pos2, pos_or_kwd, kwd1, kwd2)
a(1, 2, pos_or_kwd=3, 4, kwd2=5)

问题:运行时报错“NameError: name ‘函数名’ is not defined”

函数的定义应当写在使用的前面,要是卸载了后面,就会报这个错误:

A()
def A():
    print('使用了A函数')

Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\a.py", line 1, in 
    A()
NameError: name 'A' is not defined

A()放到整个函数的下面就好了:

def A():
    print('使用了A函数')
A()

使用了A函数

模块

一个源代码文件,就是一个模块。

建立两个源代码文件名字分别为a.pyb.py,好了,我们现在就有了两个模块,模块名称分别是ab,只不过它们里面没有代码。

示例

a模块里面写代码,然后让b模块来使用a里面的函数和变量:

def A():
    print('我是模块a.py里面的A函数')
def B():
    print('我是模块a.py里面的B函数')
x='我是模块a.py里面的x变量'

b模块里面写代码():

import a # 这句的作用:把a模块的代码导入本模块中。
a.A() # 使用a模块中的函数时,需要以方法的语法来使用,即a模块为对象,里面的函数都是其方法。

我是模块a.py里面的函数 

也可以只导入指定函数,这样就不会创建a模块这个对象了,而且可以直接使用导入的函数:

from a import A,B # 从a模块中导入A、B这两个函数
A() 
B()

我是模块a.py里面的A函数
我是模块a.py里面的B函数

也可以直接导入所有内容:

from a import *
A() 
B()
print(x)

我是模块a.py里面的A函数
我是模块a.py里面的B函数
我是模块a.py里面的x变量

句法错误

句法错误又称为解析错误。是代码没有遵守语法,导致系统无法识别时出现的错误。

示例

print("hello world!")
    print("hello world!")
print("hello world!")

该代码将报错,因为错误地使用了缩进,在语法上,此处的第二行不可以使用缩进。

异常

异常是运行时出现的错误,代码符合语法,但是不能执行。

示例

在除法计算中,0不能是除数,否则将无法进行此次除法计算。如果在程序中遇到0为除数的情况,则会发生异常:

print(1/0)

Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\b.py", line 1, in 
    print(1/0)
ZeroDivisionError: division by zero

已知的异常

对于已知的异常,在异常出现时,会给出相应的出错原因。

已知的异常罗列如下,全部用顾名思义的名称来表示(称为异常名),同时以层次结构来将异常归类,比如操作系统错误OSError,里面又分为“所需的文件不存在错误FileNotFoundError”、“权限不足错误PermissionError”。

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

处理异常:try

把可能出现异常的代码放在try的代码块里面,当其出现异常时,try会立即处理这个异常,而不会让异常使程序停止,或由系统输出错误内容。

语法

try:
    [可能出现异常的代码块]
[except [异常名 as 变量名]
    [仅出现的异常时异常名时,执行的代码块]]
except ([异常名1,异常名2,……]): # 只有一个异常名时,括号可有可无。
	[仅出现的异常是异常名1,异常名2,……时,执行的代码块]
except :
    [出现异常不属于之前的except时,执行的代码块]
else:
	[没有出现异常时,执行的代码块]
finally:
    [finally子句不论try语句是否产生了异常都会被执行]

示例:一个最简单的try

try:
    print(1/0)
except :
    print('有异常')

有异常

示例:使每个except只匹配指定的异常

try:
    print(1/0)
except NotImplementedError:
    print('NotImplementedError')
except (ZeroDivisionError,BufferError):
    print('ZeroDivisionError 或 BufferError')
except :
    print('其他异常')
else:
    print('无异常')

ZeroDivisionError 或 BufferError

示例:不带异常名的except将匹配所有异常

try:
    print(1/0)
except (NotImplementedError):
    print('NotImplementedError')
except (ConnectionRefusedError,BufferError):
    print('ConnectionRefusedError 或 BufferError')
except :
    print('其他异常')
else:
    print('无异常')
finally:
    print('finally子句不论try语句是否产生了异常都会被执行')

其他异常
finally子句不论try语句是否产生了异常都会被执行

示例:获取异常的详细说明

try:
    print(1/0)
except ZeroDivisionError as a:
    print(a)
division by zero

示例:else和finally

若try中没有发生异常,则else中的代码块将被执行。

finally子句不论try语句是否产生了异常都会被执行。finally的用处:虽然异常会导致程序中断,但finally可以再异常发生后、程序被中断之前,执行其代码。

try:
    print(1/2)
except (NotImplementedError):
    print('NotImplementedError')
except (ConnectionRefusedError,BufferError):
    print('ConnectionRefusedError 或 BufferError')
except :
    print('其他异常')
else:
    print('无异常')
finally:
    print('finally子句不论try语句是否产生了异常都会被执行')

0.5
无异常
finally子句不论try语句是否产生了异常都会被执行

示例:异常没有被任何except匹配

如果所有的except都无法匹配出现的异常,那么异常将继续存在,不过这不会影响finally的执行:

try:
    print(1/0)
except (NotImplementedError):
    print('NotImplementedError')
except (ConnectionRefusedError,BufferError):
    print('ConnectionRefusedError 或 BufferError')
else:
    print('无异常')
finally:
    print('finally子句不论try语句是否产生了异常都会被执行')

finally子句不论try语句是否产生了异常都会被执行
Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\b.py", line 2, in 
    print(1/0)
ZeroDivisionError: division by zero

类就是变量和函数的集合体。写在类里面的变量称为这个类的属性,函数称为这个类的方法。

写一个有属性、有方法的类

语法

class 类的名称:
    属性名1=数据1
    属性名2=数据2
    ……
    属性名n=数据n
    def 方法名1 ( self, 参数1……, 参数n ):
        [方法名1的代码块]
    ……
    def 方法名n ( self, 参数1……, 参数n ):
        [方法名n的代码块]

示例

class Room: # 创建一个类 Room ,来保存班级的信息
    roomName='高一三班' # 属性 roomName ,储存班级名称
    Grade1=88 # 属性 Grade1 ,储存学生1的考试分数
    Grade2=95 # 属性 Grade2 ,储存学生2的考试分数
    Grade3=80 # 属性 Grade3 ,储存学生3的考试分数
    # 方法的第一个参数必须是 self,其代表使用该方法的实例。
    def avg(self): # 方法 avg ,用来计算平均分。
        return (self.Grade1+self.Grade2+self.Grade3)/3
a=Room() # 创建一个 Room 的副本给 a,这个过程叫做创建实例。
# 此时,a 称为类 Room 的实例。
b=Room()
print(a.roomName)
print(a.avg())
a.Grade1=100 # 修改属性的数据,不同的实例互不影响。
print(a.Grade1)
print(b.Grade1)

高一三班
87.66666666666667
100
88

类、属性、方法的名称不可以相同,否则会报错:

class a:
    a='类 a 的 a 属性' # 类、属性、方法的名称不可以相同
    def a(self):
        print('类 a 的 a 方法')
    def __init__(self):
        print('类 a 的 __init__ 方法')
b=a()
print(a.a) # 使用属性

类 a 的 __init__ 方法

class a:
    a='类 a 的 a 属性' # 类、属性、方法的名称不可以相同
    def a(self):
        print('类 a 的 a 方法')
    def __init__(self):
        print('类 a 的 __init__ 方法')
b=a()
print(a.a()) # 使用方法

类 a 的 __init__ 方法
Traceback (most recent call last):
  File "C:\Users\zzs\Desktop\b.py", line 8, in 
    print(a.a()) # 使用方法
TypeError: a() missing 1 required positional argument: 'self'

写一个创建实例后,会自动执行特定代码的类

语法

名称为__init__的方法,会在创建实例后自动执行一次。

class 类的名称:
    属性名1=数据1
    def 方法名1 ( self, 参数1……, 参数n ):
        [方法名1的代码块]
    def __init__( self, 参数1……, 参数n ):
        self.data = []

示例

class Room: # 创建一个类 Room ,来保存班级的信息
    roomName='高一三班' # 属性 roomName ,储存班级名称
    Grade1=88 # 属性 Grade1 ,储存学生1的考试分数
    Grade2=95 # 属性 Grade2 ,储存学生2的考试分数
    Grade3=80 # 属性 Grade3 ,储存学生3的考试分数
    def avg(self): # 方法 avg ,用来计算平均分。
        return (self.Grade1+self.Grade2+self.Grade3)/3
    def __init__(self,a,b,c): # 创建实例后自动执行一次该方法
        self.Grade1=a
        self.Grade2=b
        self.Grade3=c
a=Room(80,90,100) # 创建实例时传入参数,这些参数会传递给__init__方法。
print(a.Grade1)
print(a.avg())
a.__init__(50,60,70) # __init__方法也像其它方法一样,可以调用。
print(a.avg())

80
90.0
60.0

利用其他的类的方法和属性来创建一个类:继承

继承就是指定需要利用的类,然后就可以把那个类的属性、方法囊括到自己的类中。

被利用的类称为基类或父类,新创建的类称为派生类或子类。

语法

名称为__init__的方法,会在创建实例后自动执行一次。

class 类的名称(父类名称1,父类名称2……父类名称n):
    属性名1=数据1
    def 方法名1 ( self, 参数1……, 参数n ):
        [方法名1的代码块]
    def __init__( self, 参数1……, 参数n ):
        self.data = []

示例

class a:
    aa='类 a 的 aa 属性'
    def aaa(self):
        print('类 a 的 aaa 方法')
    def __init__(self):
        print('类 a 的 __init__ 方法')
class b:
    bb='类 b 的 bb 属性'
    def bbb(self):
        print('类 b 的 bbb 方法')
    def __init__(self):
        print('类 b 的 __init__ 方法')
class c(a,b): # c 利用 a、b 的属性和方法
    cc='类 c 的 cc 属性'
    def ccc(self):
        print('类 c 的 ccc 方法')
    def __init__(self):
        print('类 c 的 __init__ 方法')
d=c() # 创建 c 的实例
# 调用属性、方法时,根据其名称,先在子类中寻找。
# 若没找到,再根据代码中父类的顺序,从左向右,依次寻找。
print(d.cc)
print(d.bb)
print(d.aa)
d.ccc()
d.bbb()
d.aaa()

类 c 的 __init__ 方法
类 c 的 cc 属性
类 b 的 bb 属性
类 a 的 aa 属性
类 c 的 ccc 方法
类 b 的 bbb 方法
类 a 的 aaa 方法

标准库

标准库就是python自带的模块。

以下罗列部分常用模块,然后举个小例子来介绍如何使用他们。

多种操作系统接口:os 模块

os 模块提供了一种使用与操作系统相关的功能的便捷式途径。

Unix 风格路径名模式扩展:glob 模块

glob 模块可根据 Unix 终端所用规则找出所有匹配特定模式的路径名,但会按不确定的顺序返回结果。

系统相关的参数和函数:sys 模块

sys 模块提供了一些变量和函数。这些变量可能被解释器使用,也可能由解释器提供。这些函数会影响解释器。本模块总是可用的。

正则表达式操作:re 模块

re 模块提供了与 Perl 语言类似的正则表达式匹配操作。

数学函数:math 模块

math 模块提供了对C标准定义的数学函数的访问。

生成伪随机数:random 模块

random 模块实现了各种分布的伪随机数生成器。

数学统计函数:statistics 模块

statistics 模块提供了用于计算数字 (Real-valued) 数据的数理统计量的函数。

用于打开 URL 的可扩展库:urllib.request 模块

urllib.request 模块定义了适用于在各种复杂情况下打开 URL(主要为 HTTP)的函数和类 — 例如基本认证、摘要认证、重定向、cookies 及其它。

SMTP协议客户端:smtplib 模块

smtplib 模块定义了一个 SMTP 客户端会话对象,该对象可将邮件发送到 Internet 上带有 SMTP 或 ESMTP 接收程序的计算机。

基本的日期和时间类型:datetime 模块

datetime 模块提供用于处理日期和时间的类。

数据压缩:zlib、gzip、bz2、lzma、zipfile、tarfile 模块

常见的数据存档和压缩格式由模块直接支持。

测量小代码片段的执行时间:timeit 模块

timeit 模块提供了一种简单的方法来计算一小段 Python 代码的耗时。它有 命令行界面 以及一个 可调用 方法。它避免了许多用于测量执行时间的常见陷阱。

测试交互性的Python示例:doctest 模块

doctest 模块寻找像Python交互式代码的文本,然后执行这些代码来确保它们的确就像展示的那样正确运行。

基于线程的并行:threading 模块

threading 模块在较低级的模块 _thread 基础上建立较高级的线程接口。

另一种 repr() 实现:reprlib 模块

reprlib 模块提供了一种对象表示的产生方式,它会对结果字符串的大小进行限制。 该方式被用于 Python 调试器,也适用于某些其他场景。

示例

按照模块的语法进行使用即可。

查看os模块中的关于浮点数的系统信息:

import sys
print('sys.float_info.epsilon:')
print(sys.float_info.epsilon)
print('sys.float_info.dig:')
print(sys.float_info.dig)
print('sys.float_info.mant_dig:')
print(sys.float_info.mant_dig)
print('sys.float_info.max:')
print(sys.float_info.max)
print('sys.float_info.max_exp:')
print(sys.float_info.max_exp)
print('sys.float_info.max_10_exp:')
print(sys.float_info.max_10_exp)
print('sys.float_info.min:')
print(sys.float_info.min)
print('sys.float_info.min_exp:')
print(sys.float_info.min_exp)
print('sys.float_info.min_10_exp:')
print(sys.float_info.min_10_exp)
print('sys.float_info.radix:')
print(sys.float_info.radix)
print('sys.float_info.rounds:')
print(sys.float_info.rounds)

sys.float_info.epsilon:
2.220446049250313e-16
sys.float_info.dig:
15
sys.float_info.mant_dig:
53
sys.float_info.max:
1.7976931348623157e+308
sys.float_info.max_exp:
1024
sys.float_info.max_10_exp:
308
sys.float_info.max:
2.2250738585072014e-308
sys.float_info.min_exp:
-1021
sys.float_info.min_10_exp:
-307
sys.float_info.radix:
2
sys.float_info.rounds:
1

电脑中的零和一,如何转换成我们的看得懂的信息

需要显示给我们看的信息分为数字、文字、媒体。

数字

整数直接转换成二进制数保存。

小数转换成指数表示法,即转换成整数和指数两部分,指数表示法中的这两部分都是整数,再转换成二进制保存。

文字

每个字都有自己的编号,这个编号是整数,保存这个整数即可。

不同的字对应不同的编号,这个对应关系称为编码,世界上有多种编码,即多种对应关系。python中默认的编码叫做utf-8,我们常用的还有ascii

媒体

媒体多种多样,比如声音、图片,他们使用和文字类似的保存方式。

声音有各种表示方式,比如振幅、波形表示,比如光谱表示,再以不同的编码来表示这些内容。

图片也是,有些图片通过记录位置、颜色来表示,有些记录线条的起止点、弯曲度来表示,再以不同的编码来表示这些内容。

编码风格

python官方建议使用PEP8规定的风格来写代码。它推行的编码风格易于阅读、赏心悦目。Python 开发者均应抽时间悉心研读;以下是该提案中的核心要点:

  • 缩进,用 4 个空格,不要用制表符。
  • 4 个空格是小缩进(更深嵌套)和大缩进(更易阅读)之间的折中方案。制表符会引起混乱,最好别用。
  • 换行,一行不超过 79 个字符。
  • 这样换行的小屏阅读体验更好,还便于在大屏显示器上并排阅读多个代码文件。
  • 用空行分隔函数和类,及函数内较大的代码块。
  • 最好把注释放到单独一行。
  • 使用文档字符串。
  • 运算符前后、逗号后要用空格,但不要直接在括号内使用: a = f(1, 2) + g(3, 4)。
  • 类和函数的命名要一致;按惯例,命名类用 UpperCamelCase,命名函数与方法用 lowercase_with_underscores。命名方法中第一个参数总是用 self (类和方法详见 初探类)。
  • 编写用于国际多语环境的代码时,不要用生僻的编码。Python 默认的 UTF-8 或纯 ASCII 可以胜任各种情况。
  • 同理,就算多语阅读、维护代码的可能再小,也不要在标识符中使用非 ASCII 字符。

你可能感兴趣的:(python,3.9.5,教程)