一、Python环境下载:
-
提取码:0st4
二、Python安装步骤:
1、点击python-3.8.1-amd64.exe
2、选择安装方式(推荐为自定义安装):
3、选择需要安装组件:
4、设置安装路径及安装部件:
三、配置环境变量:
1、右键点击"计算机",然后点击"属性"
2、然后点击"高级系统设置"
3、选择"系统变量"窗口下面的"Path",双击即可
4、然后在"Path"行,添加python安装路径即可(我的D:\Python32),所以在后面,添加该路径即可
四、配置Python编译环境:
1、备注:
(1)安装python环境时已经在python目录下存在python.exe编译器,但是该编译器不适合大型项目构建。
(2)此处安装的是sublime text3环境。
a、百度网盘链接:https://pan.baidu.com/s/1K2zHV6r4ZzGcrSh--IdpkQ
b、提取码:kxxi
2、配置编译环境:
(1)打开sublime,依次点击菜单Tools-->Build System-->New Build System
(2)打开后会生成新的一个配置文件:
(3)你需要复制粘贴以下代码到配置文件中:
{
"cmd": ["XXXX","-u","$file"],
"file_regex":"^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector":"source.python",
}
*注意:其中的 XXXX 代表你安装Python3时的python.exe安装路径
如:D:/xxx/python.exe(注意反斜杠)
(4)测试:
a、Ctrl+B 编译python程序。
五、Python保留字:
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
六、Python编码集:
UTF-8
七、标识符:
- 第一个字符必须是字母表中字母或下划线 _ 。
- 标识符的其他的部分由字母、数字和下划线组成。
- 标识符对大小写敏感。
八、注释:
- 单行注释:#
- 多行注释:''' 或 """
九、缩进:
1、Python不使用{}标定代码段,使用缩进表示代码段,不同缩进表示不同·代码段。
如:
if True:
print ("True")
else:
print ("False")
运行正确。
而:
f True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
运行失败,IndentationError: unindent does not match any outer indentation level
十、多行语句:
1、使用反斜杠(\)来实现多行语句:
total = item_one + \
item_two + \
item_three
2、在 [], {}, 或 () 中的多行语句,不需要使用反斜杠(\):
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
十一、数字(Number)类型:
1、int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
2、bool (布尔), 如 True。
3、float (浮点数), 如 1.23、3E-2
4、complex (复数), 如 1 + 2j、 1.1 + 2.2j (科学计算时使用)
十一、字符串(String):
- python中单引号和双引号使用完全相同。
- 使用三引号('''或""")可以指定一个多行字符串。
- 转义符 '\'
- 反斜杠可以用来转义,使用r可以让反斜杠不发生转义。。 如 r"this is a line with \n" 则\n会显示,并不是换行。
- 按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
- 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
- Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
- Python中的字符串不能改变。
- Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
- 字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
如:
str='Runoob'
word = '字符串' #单引号和双引号使用完全相同
sentence = "这是一个句子。" "这是另一个句子。" #按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
paragraph = """这是一个段落,
可以由多行组成""" #使用三引号('''或""")可以指定一个多行字符串
print(word) # 输出字符串
print(sentence) # 输出字符串
print(paragraph) # 输出字符串
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第五个的字符
print(str[2:]) # 输出从第三个开始后的所有字符
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print('------------------------------')
print('hello\nrunoob') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\nrunoob') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义
输出:
字符串
这是一个句子。这是另一个句子。
这是一个段落,
可以由多行组成
Runoob
Runoo
R
noo
noob
RunoobRunoob
Runoob你好
------------------------------
hello
runoob
hello\nrunoob
十二、空行:
空行表示分隔类和函数,便于日后维护,本身并不是Python语法,不分隔也不会编译报错
十三、等待用户输入:
1、代码:
str = input("按下 enter 键后退出:\n") #\n\n在结果输出前会输出两个新的空行"\n\n按下 enter 键后退出。"
print ("你输入的内容是: ", str)
2、sublime text3 加载Python3 指令编译器实现用户键盘输入:
(1)转到对应的GiiHub地址:https://github.com/wbond/package_control,下载package control包
(2)解压文件,点击首选项->浏览插件,在打开的文件夹中将解压文件复制
(3)ctrl+shift+P输入install选择“PackageControl: Install Package”
(4)在弹出的界面内输入sublimeREPL回车等待安装完成
(5)完成后重启SublimeText3,如果菜单项Tools下出现sublimeREPL,则安装成功。
(6)测试,选择sublimeREPL->Python - RUN current file若结果如则成功:
按下 enter 键后退出:
1235嗡嗡嗡!!!qwq
你输入的内容是: 1235嗡嗡嗡!!!qwq
***Repl Closed***
(7)添加快捷键,Preferences->Key Bindings - User ,输入以下内容:
[
{"keys":["ctrl+r"] ,
"caption": "SublimeREPL: Python - RUN current file",
"command": "run_existing_window_command",
"args":
{
"id": "repl_python_run",
"file": "config/Python/Main.sublime-menu"
}
},
]
十四、多行语句输出:
输入以下语句:
import sys; x = 'runoob'; sys.stdout.write(x + '\n')
输出结果:
runoob
十五、多个语句构成代码组:
概念:缩进相同的一组语句构成一个代码块
作用:使用if、while、def和class这样的复合语句时,标定多少行代码属于同一代码组
使用方法:首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组(即子句(clause))
示例:
a = 100;
if a<100 :
print("a<100")
elif a==100 :
print("a=100")
else :
print("a>100")
输出结果:
a=100
十六、Print输出:
print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="",或是直接使用,号:
示例:
x="a"
y="b"
print('换行输出:')
print( x )
print( y )
print('不换行输出1:')
print( x, end=" " )
print( y, end=" " )
print()
print('不换行输出2:')
print(x,y)
输出结果:
换行输出:
a
b
不换行输出1:
a b
不换行输出2:
a b
十七、导入:
- 将整个模块(somemodule)导入,格式为: import somemodule
- 从某个模块中导入某个函数,格式为: from somemodule import somefunction
- 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
- 将某个模块中的全部函数导入,格式为: from somemodule import *
示例:(导入 sys 模块)
import sys
print('================Python import mode==========================')
print ('命令行参数为:')
for i in sys.argv:
print (i)
print ('\n'+'python 路径为',sys.path)
输出结果:
================Python import mode==========================
命令行参数为:
D:\Python_Src\导入\import.py
python 路径为 ['D:\\Python_Src\\导入', 'D:\\Python\\python38.zip', 'D:\\Python\\DLLs', 'D:\\Python\\lib', 'D:\\Python', 'D:\\Python\\lib\\site-packages']
示例:(导入 sys 模块的 argv,path 成员)
from sys import argv,path # 导入特定的成员
print('================python from import===================================')
print ('命令行参数为:')
for i in argv:
print (i)
print('\n'+'path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path
输出结果:
================python from import===================================
命令行参数为:
D:\Python_Src\导入\from_import.py
path: ['D:\\Python_Src\\导入', 'D:\\Python\\python38.zip', 'D:\\Python\\DLLs', 'D:\\Python\\lib', 'D:\\Python', 'D:\\Python\\lib\\site-packages']
十八、赋值:
Python是解释型语言赋值直接使用=将右边数字赋值左边变量,如:
counter = 100 # 整型变量
miles = 1000.0 # 浮点型变量
name = "runoob" # 字符串
print (counter)
print (miles)
print (name)
输出结果:
100
1000.0
runoob
Python 支持多个变量同时赋值,以下格式也可以编译执行:
counter1 = counter2 = counter3 = 100 # 一个数据赋值多个变量
temp1 , temp2 , temp3 = 10 , 100.123 , "runoob" #多个数据赋值多个变量
print (counter1)
print (counter2)
print (counter3)
print (temp1)
print (temp2)
print (temp3)
输出结果:
100
100
100
10
100.123
runoob
十九、数据类型:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
1、Number(数字):
(1)基础概念:
Python3 支持 int、float、bool、complex(复数)。
在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
内置的 type() 函数可以用来查询变量所指的对象类型。
此外还可以用 isinstance 来判断是否属于某一数据类型。
isinstance 和 type 的区别在于:
-
type()不会认为子类是一种父类类型。
-
isinstance()会认为子类是一种父类类型。
示例代码:
a, b, c, d = 20, 5.5, True, 4+3j
print(type(a), type(b), type(c), type(d)) #查询变量所指的对象类型
print(isinstance(a, int),isinstance(a, float)) #判断是否属于某一数据类型
输出结果:
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
True False
注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。
(2)数值运算:
print("————————————————————————————————————————————————————————")
print(1 + 2) # 1、加法
print(4.3 - 2) # 2、减法
print(3 * 7) # 3、乘法
print(2 / 4) # 4、除法
print(2 // 4) # 5、除法获得整数
print(17 % 3) # 6、求余
print(2 ** 5) # 7、乘方
输出结果:
————————————————————————————————————————————————————————
3
2.3
21
0.5
0
2
32
2、String(字符串):
(1)定义:
Python中的字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符
(2)字符串截取:
语法:变量[头下标:尾下标]
备注:从头取值开始下标为0,从尾取值开始下班为-1
示例:
str = 'Runoob'
print (str) # 输出字符串
print (str[0:-1]) # 输出第一个到倒数第二个的所有字符
print (str[0]) # 输出字符串第一个字符
print (str[2:5]) # 输出从第三个开始到第五个的字符
print (str[2:]) # 输出从第三个开始的后的所有字符
print (str * 2) # 输出字符串两次
print (str + "TEST") # 连接字符串
输出:
Runoob
Runoo
R
noo
noob
RunoobRunoob
RunoobTEST
3、Tuple(元组):
(1)定义:
不可修改的数据集合,允许内容为数字、字符串、嵌套列表
(2)格式:
变量名=('数值1','数值2','数值3',...)
示例:
tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2 )
(3)截取列表格式:
变量(头下标:尾下标)
示例:
tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2 )
tinytuple = (123, 'runoob',tuple)
print (tuple) # 输出完整元组
print (tuple[0]) # 输出元组的第一个元素
print (tuple[1:3]) # 输出从第二个元素开始到第三个元素
print (tuple[2:]) # 输出从第三个元素开始的所有元素
print (tinytuple * 2) # 输出两次元组
print (tuple + tinytuple) # 连接元组
输出结果:
('abcd', 786, 2.23, 'runoob', 70.2)
abcd
(786, 2.23)
(2.23, 'runoob', 70.2)
(123, 'runoob', ('abcd', 786, 2.23, 'runoob', 70.2), 123, 'runoob', ('abcd', 786, 2.23, 'runoob', 70.2))
('abcd', 786, 2.23, 'runoob', 70.2, 123, 'runoob', ('abcd', 786, 2.23, 'runoob', 70.2))
4、List(列表):
(1)定义:
可修改的数据集合,允许内容为数字、字符串、嵌套列表
(2)格式:
变量名=['数值1','数值2','数值3',...]
示例:
list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ]
tinylist = [123, 'runoob',list]
(3)截取列表格式:
变量[头下标:尾下标]
示例:
list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ]
tinylist = [123, 'runoob',list]
print (list) # 输出完整列表
print (list[0]) # 输出列表第一个元素
print (list[1:3]) # 从第二个开始输出到第三个元素
print (list[2:]) # 输出从第三个元素开始的所有元素
print (tinylist * 2) # 输出两次列表
print (list + tinylist) # 连接列表
输出结果:
['abcd', 786, 2.23, 'runoob', 70.2]
abcd
[786, 2.23]
[2.23, 'runoob', 70.2]
[123, 'runoob', ['abcd', 786, 2.23, 'runoob', 70.2], 123, 'runoob', ['abcd', 786, 2.23, 'runoob', 70.2]]
['abcd', 786, 2.23, 'runoob', 70.2, 123, 'runoob', ['abcd', 786, 2.23, 'runoob', 70.2]]
?(4)截取List:(函数+List截取)
def reverseWords(input):
# 通过空格将字符串分隔符,把各个单词分隔为列表
inputWords = input.split(" ")
# 翻转字符串
# 假设列表 list = [1,2,3,4],
# list[0]=1, list[1]=2 ,而 -1 表示最后一个元素 list[-1]=4 ( 与 list[3]=4 一样)
# inputWords[-1::-1] 有三个参数
# 第一个参数 -1 表示最后一个元素
# 第二个参数为空,表示移动到列表末尾
# 第三个参数为步长,-1 表示逆向
inputWords=inputWords[-1::-1]
# 重新组合字符串
output = ' '.join(inputWords)
return output
if __name__ == "__main__":
input = 'I like runoob'
rw = reverseWords(input)
print(rw)
输出结果:
runoob like I
5、Dictionary(字典):
(1)定义:
类似于Java的Map
无序对象集合
使用键值对存储
键(key)必须使用不可变类型(但是键名可以自定义)
(2)格式:
dict['key'] = "value"
示例:
dict = {}
dict['one'] = "1 - 菜鸟教程"
dict[2] = "2 - 菜鸟工具"
tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}
print (dict['one']) # 输出键为 'one' 的值
print (dict[2]) # 输出键为 2 的值
print (tinydict) # 输出完整的字典
print (tinydict.keys()) # 输出所有键
print (tinydict.values()) # 输出所有值
输出结果:
1 - 菜鸟教程
2 - 菜鸟工具
{'name': 'runoob', 'code': 1, 'site': 'www.runoob.com'}
dict_keys(['name', 'code', 'site'])
dict_values(['runoob', 1, 'www.runoob.com'])
6、Set(集合):
(1)定义:
不可重复的无序的可修改的数据类型集,多用于数据集合的交并补非操作
(2)创建格式:
parame = {value01,value02,...}
或者
set(value)
注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
示例:
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
print(student) # 输出集合,重复的元素被自动去掉
# 成员测试
if 'Rose' in student :
print('Rose 在集合中')
else :
print('Rose 不在集合中')
# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(a - b) # a 和 b 的差集
print(a | b) # a 和 b 的并集
print(a & b) # a 和 b 的交集
print(a ^ b) # a 和 b 中不同时存在的元素
结果:
{'Jim', 'Rose', 'Tom', 'Jack', 'Mary'}
Rose 在集合中
{'c', 'b', 'a', 'd', 'r'}
{'b', 'd', 'r'}
{'c', 'b', 'a', 'm', 'l', 'd', 'z', 'r'}
{'a', 'c'}
{'d', 'z', 'r', 'b', 'm', 'l'}
二十、删除数据:
数据被赋值时即创建,调用del语句可以删除对象
格式:
del var1[,var2[,var3[....,varN]]]
单个删除:
#赋值
var_a = 1
var_b = 1.0
var_c = "str"
var_d = 2+3j
#删除单个引用
del var_a
#输出
#print(var_a,var_b,var_c,var_d) #报错因为var_a引用已被删除
print(var_b,var_c,var_d)
输出结果:
1.0 str (2+3j)
多个删除:
#赋值
var_a = 1
var_b = 1.0
var_c = "str"
var_d = 2+3j
#删除多个引用
del var_a,var_b,var_c
#输出
#print(var_a,var_b,var_c,var_d) #报错因为var_a,var_b,var_c引用已被删除
print(var_d)
输出结果:
(2+3j)
二十一、Python数据类型转换:
二十二、Python3 运算符:
1、算术运算符 :
print("————————————————————————————————————————————————————————")
print(1 + 2) # 1、加法
print(4.3 - 2) # 2、减法
print(3 * 7) # 3、乘法
print(2 / 4) # 4、除法
print(2 // 4) # 5、除法获得整数
print(17 % 3) # 6、求余
print(2 ** 5) # 7、乘方
输出结果:
————————————————————————————————————————————————————————
3
2.3
21
0.5
0
2
32
2、比较(关系)运算符:
示例:
a = 21
b = 10
c = 0
if ( a == b ): # 等于 - 比较对象是否相等
print ("1 - a 等于 b")
else:
print ("1 - a 不等于 b")
if ( a != b ): # 不等于 - 比较两个对象是否不相等
print ("2 - a 不等于 b")
else:
print ("2 - a 等于 b")
if ( a < b ): # 小于 - 返回x是否大于y
print ("3 - a 小于 b")
else:
print ("3 - a 大于等于 b")
if ( a > b ): # 大于 - 返回x是否大于y
print ("4 - a 大于 b")
else:
print ("4 - a 小于等于 b")
# 修改变量 a 和 b 的值
a = 5;
b = 20;
if ( a <= b ): # 小于等于 - 返回x是否小于等于y。
print ("5 - a 小于等于 b")
else:
print ("5 - a 大于 b")
if ( b >= a ): # 大于等于 - 返回x是否大于等于y
print ("6 - b 大于等于 a")
else:
print ("6 - b 小于 a")
输出结果:
1 - a 不等于 b
2 - a 不等于 b
3 - a 大于等于 b
4 - a 大于 b
5 - a 小于等于 b
6 - b 大于等于 a
3、赋值运算符 :
示例:
a = 21
b = 10
c = 0
c = a + b # 简单的赋值运算符
print ("1 - c 的值为:", c)
c += a # 加法赋值运算符
print ("2 - c 的值为:", c)
c *= a # 乘法赋值运算符
print ("3 - c 的值为:", c)
c /= a # 除法赋值运算符
print ("4 - c 的值为:", c)
c = 2 # 简单的赋值运算符
c %= a # 取余赋值运算符
print ("5 - c 的值为:", c)
c **= a # 求乘方赋值运算符
print ("6 - c 的值为:", c)
c //= a # 除数求整赋值运算符
print ("7 - c 的值为:", c)
c -= a # 减法赋值运算符
print ("8 - c 的值为:", c)
输出结果:
1 - c 的值为: 31
2 - c 的值为: 52
3 - c 的值为: 1092
4 - c 的值为: 52.0
5 - c 的值为: 2
6 - c 的值为: 2097152
7 - c 的值为: 99864
8 - c 的值为: 99843
4、逻辑运算符 :
示例:
a = 10
b = 20
if ( a and b ):
print ("1 - 变量 a 和 b 都为 true")
else:
print ("1 - 变量 a 和 b 有一个不为 true")
if ( a or b ):
print ("2 - 变量 a 和 b 都为 true,或其中一个变量为 true")
else:
print ("2 - 变量 a 和 b 都不为 true")
# 修改变量 a 的值
a = 0
if ( a and b ):
print ("3 - 变量 a 和 b 都为 true")
else:
print ("3 - 变量 a 和 b 有一个不为 true")
if ( a or b ):
print ("4 - 变量 a 和 b 都为 true,或其中一个变量为 true")
else:
print ("4 - 变量 a 和 b 都不为 true")
if not( a and b ):
print ("5 - 变量 a 和 b 都为 false,或其中一个变量为 false")
else:
print ("5 - 变量 a 和 b 都为 true")
输出结果:
1 - 变量 a 和 b 都为 true
2 - 变量 a 和 b 都为 true,或其中一个变量为 true
3 - 变量 a 和 b 有一个不为 true
4 - 变量 a 和 b 都为 true,或其中一个变量为 true
5 - 变量 a 和 b 都为 false,或其中一个变量为 false
5、位运算符 :
示例:
a = 60 # 60 = 0011 1100
b = 13 # 13 = 0000 1101
c = 0
c = a & b; # 12 = 0000 1100 #按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
print ("1 - c 的值为:", c)
c = a | b; # 61 = 0011 1101 # 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
print ("2 - c 的值为:", c)
c = a ^ b; # 49 = 0011 0001 #按位异或运算符:当两对应的二进位相异时,结果为1
print ("3 - c 的值为:", c)
c = ~a; # -61 = 1100 0011 # 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1
print ("4 - c 的值为:", c)
c = a << 2; # 240 = 1111 0000 #左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。
print ("5 - c 的值为:", c)
c = a >> 2; # 15 = 0000 1111 #右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数
print ("6 - c 的值为:", c)
输出结果:
1 - c 的值为: 12
2 - c 的值为: 61
3 - c 的值为: 49
4 - c 的值为: -61
5 - c 的值为: 240
6 - c 的值为: 15
6、成员(列从属)运算符:
示例:
a = 10
b = 20
list = [1, 2, 3, 4, 5 ];
if ( a in list ):
print ("1 - 变量 a 在给定的列表中 list 中")
else:
print ("1 - 变量 a 不在给定的列表中 list 中")
if ( b not in list ):
print ("2 - 变量 b 不在给定的列表中 list 中")
else:
print ("2 - 变量 b 在给定的列表中 list 中")
# 修改变量 a 的值
a = 2
if ( a in list ):
print ("3 - 变量 a 在给定的列表中 list 中")
else:
print ("3 - 变量 a 不在给定的列表中 list 中")
输出结果:
1 - 变量 a 不在给定的列表中 list 中
2 - 变量 b 不在给定的列表中 list 中
3 - 变量 a 在给定的列表中 list 中
7、身份(类及引用判断)运算符 :
示例:
a = 20
b = 20
if ( a is b ): #类判断是否相同
print ("1 - a 和 b 有相同的标识")
else:
print ("1 - a 和 b 没有相同的标识")
if ( id(a) == id(b) ): #引用判断是否相同
print ("2 - a 和 b 有相同的标识")
else:
print ("2 - a 和 b 没有相同的标识")
# 修改变量 b 的值
b = 30
if ( a is b ): #类判断是否相同
print ("3 - a 和 b 有相同的标识")
else:
print ("3 - a 和 b 没有相同的标识")
if ( a is not b ): #类判断是否相同
print ("4 - a 和 b 没有相同的标识")
else:
print ("4 - a 和 b 有相同的标识")
输出结果:
1 - a 和 b 有相同的标识
2 - a 和 b 有相同的标识
3 - a 和 b 没有相同的标识
4 - a 和 b 没有相同的标识
is 与 == 区别:
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
>>>a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True
8、运算符优先级:
以下表格列出了从最高到最低优先级的所有运算符:
()可以提高运算符优先级
二十三、Number方法:
数学函数:
随机数函数:
三角函数:
数学常量:
二十四、字符串方法:
1、Python转义字符:
2、Python字符串运算符:(a表示"Hello"、b表示"Python")
a = "Hello"
b = "Python"
print("a + b 输出结果:", a + b)
print("a * 2 输出结果:", a * 2)
print("a[1] 输出结果:", a[1])
print("a[1:4] 输出结果:", a[1:4])
if( "H" in a) :
print("H 在变量 a 中")
else :
print("H 不在变量 a 中")
if( "M" not in a) :
print("M 不在变量 a 中")
else :
print("M 在变量 a 中")
print (r'\n')
print (R'\n')
a + b 输出结果: HelloPython
a * 2 输出结果: HelloHello
a[1] 输出结果: e
a[1:4] 输出结果: ell
H 在变量 a 中
M 不在变量 a 中
\n
\n
3、Python字符串格式化:
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
我叫 小明 今年 10 岁!
4、Python三引号:(创建跨行字符串)
应用场景:
创建HTML文本
创建SQL语句
errHTML = '''
<HTML><HEAD><TITLE>
Friends CGI Demo</TITLE></HEAD>
<BODY><H3>ERROR</H3>
<B>%s</B><P>
<FORM><INPUT TYPE=button VALUE=Back
ONCLICK="window.history.back()"></FORM>
</BODY></HTML>
'''
cursor.execute('''
CREATE TABLE users (
login VARCHAR(8),
uid INTEGER,
prid INTEGER)
''')
para_str = """这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print (para_str)
这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( )。
也可以使用换行符 [
]。
5、f-string:(字面量格式化字符串,替代%的快速格式化)
name = 'Runoob'
word = f'Hello {name}' # 替换变量
print(word)
print(f'{1+2}')
Hello Runoob
3
6、Python 的字符串内建函数:
二十五、列表(List)方法:
1、删除列表元素:
list = ['Google', 'Runoob', 1997, 2000]
print ("原始列表 : ", list)
del list[2]
print ("删除第三个元素 : ", list)
原始列表 : ['Google', 'Runoob', 1997, 2000]
删除第三个元素 : ['Google', 'Runoob', 2000]
2、Python列表脚本操作符:
3、Python列表截取与拼接:
4、嵌套列表:
5、Python列表函数&方法:
二十六、元组:
1、删除元组:(会报错)
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup # 报错,因为元组不可修改
print ("删除后的元组 tup : ")
print (tup)
2、元组运算符:
3、元组索引,截取:
4、元组内置函数:
5、关于元组是不可变的原因是因为元组内容指向的内存地址不可变
>>> tup = ('r', 'u', 'n', 'o', 'o', 'b')
>>> tup[0] = 'g' # 不支持修改元素
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> id(tup) # 查看内存地址
4440687904
>>> tup = (1,2,3)
>>> id(tup)
4441088800 # 内存地址不一样了
二十七、判断语句:
1、单判断:
var1 = 100
if var1:
print ("1 - if 表达式条件为 true")
print (var1)
var2 = 0
if var2:
print ("2 - if 表达式条件为 true")
print (var2)
print ("Good bye!")
1 - if 表达式条件为 true
100
Good bye!
2、多判断:
age = int(input("请输入你家狗狗的年龄: "))
print("")
if age <= 0:
print("你是在逗我吧!")
elif age == 1:
print("相当于 14 岁的人。")
elif age == 2:
print("相当于 22 岁的人。")
elif age > 2:
human = 22 + (age -2)*5
print("对应人类年龄: ", human)
请输入你家狗狗的年龄: 11
对应人类年龄: 67
***Repl Closed***
3、判断嵌套:
num=int(input("输入一个数字:"))
if num%2==0:
if num%3==0:
print ("你输入的数字可以整除 2 和 3")
else:
print ("你输入的数字可以整除 2,但不能整除 3")
else:
if num%3==0:
print ("你输入的数字可以整除 3,但不能整除 2")
else:
print ("你输入的数字不能整除 2 和 3")
输入一个数字:10
你输入的数字可以整除 2,但不能整除 3
二十八、循环:
1、while:
n = 100
sum = 0
counter = 1
while counter <= n:
sum = sum + counter
counter += 1
print("1 到 %d 之和为: %d" % (n,sum))
1 到 100 之和为: 5050
2、while...else:
count = 0
while count < 5:
print (count, " 小于 5")
count = count + 1
else:
print (count, " 大于或等于 5")
0 小于 5
1 小于 5
2 小于 5
3 小于 5
4 小于 5
5 大于或等于 5
3、for...else:
sites = ["Baidu", "Google","Runoob","Taobao"]
for site in sites:
if site == "Runoob":
print("菜鸟教程!")
break
print("循环数据 " + site)
else:
print("没有循环数据!")
print("完成循环!")
循环数据 Baidu
循环数据 Google
菜鸟教程!
完成循环!
4、跳出循环:
(1)break:
n = 5
while n > 0:
n -= 1
if n == 2:
break
print(n)
print('循环结束。')
4
3
循环结束。
(2)continut:
n = 5
while n > 0:
n -= 1
if n == 2:
continue
print(n)
print('循环结束。')
4
3
1
0
循环结束。
5、pass(占位)语句:
for letter in 'Runoob':
if letter == 'o':
pass
print ('执行 pass 块')
print ('当前字母 :', letter)
print ("Good bye!")
当前字母 : R
当前字母 : u
当前字母 : n
执行 pass 块
当前字母 : o
执行 pass 块
当前字母 : o
当前字母 : b
Good bye!
二十九、迭代器:
1、定义:
(1)访问集合元素的一种方式
(2)迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退
(3)迭代器有两个基本的方法:iter() 和 next()
(4)字符串,列表或元组对象都可用于创建迭代器
2、迭代器示例:
import sys # 引入 sys 模块
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
"""
print ("#—next()函数,遍历内存地址——————————————————————————————————————————#")
while True:
try:
print (next(it),end=" ")
except StopIteration:
sys.exit() #搭配next()函数,退出编译器,之后不编译
print ()
print ()
"""
print ("#—迭代器输出——————————————————————————————————————————#")
for x in it:
print (x, end=" ")
print ()
print ()
print ("#—直接列表输出——————————————————————————————————————————#")
for x in list:
print (x, end=" ")
print ()
print ()
#—迭代器输出——————————————————————————————————————————#
1 2 3 4
#—直接列表输出——————————————————————————————————————————#
1 2 3 4
3、创建自定义迭代器:
class MyNumbers:
def __iter__(self): #自定义迭代器初始化方法,self为this指针
self.a = 1
return self
def __next__(self): #自定义迭代器移位方法,self为this指针
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
1
2
3
4
5
4、使用自定义迭代器中断关键字实现预防无限生成迭代器元素:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
三十、生成器:
1、定义:
(1)是一个具有yield关键字的函数
(2)生成器是一个返回迭代器的函数,只能用于迭代操作
(3)yield关键字为中断标记
(4)每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行
2、示例:
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
0 1 1 2 3 5 8 13 21 34 55
三十一、函数:
1、定义:
-
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
-
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
-
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
-
函数内容以冒号起始,并且缩进。
-
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
2、语法:
def 函数名(参数列表):
函数体
3、函数定义及返回:
print("#--无参数无返回值函数--------------------------------------------------------")
def NoRe() :
a = 10
print(a)
b = NoRe()
b #引用
NoRe() #调用
print()
print("#--无参数有返回值函数--------------------------------------------------------")
def Re() :
a = 10
return a
b = Re()
print(b) #引用
print(Re()) #调用
print()
print("#--单参数无返回值函数--------------------------------------------------------")
def NoRe(a) :
print(a)
b = NoRe(1)
b #引用
NoRe(1) #调用
print()
print("#--单参数有返回值函数--------------------------------------------------------")
def Re(a) :
return a
b = Re(1)
print(b) #引用
print(Re(1)) #调用
print()
print("#--多参数无返回值函数--------------------------------------------------------")
def NoRe(a , b) :
print(a + b)
b = NoRe(1,2)
b #引用
NoRe(1,2) #调用
print()
print("#--多参数有返回值函数--------------------------------------------------------")
def Re(a , b) :
return a + b
b = Re(1,2)
print(b) #引用
print(Re(1,2)) #调用
print()
print("#--可写函数说明--------------------------------------------------------")
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
#--无参数无返回值函数--------------------------------------------------------
10
10
#--无参数有返回值函数--------------------------------------------------------
10
10
#--单参数无返回值函数--------------------------------------------------------
1
1
#--单参数有返回值函数--------------------------------------------------------
1
1
#--多参数无返回值函数--------------------------------------------------------
3
3
#--多参数有返回值函数--------------------------------------------------------
3
3
#--可写函数说明--------------------------------------------------------
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
4、不定长参数函数:
print("#--*元组不定长函数输出--------------------------------------------------------")
# 可写函数说明
def printinfo( arg1, *vartuple ): #加星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vartuple)
# 调用printinfo 函数
printinfo( 10 ) #如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。
printinfo( 70, 60, 50 )
print()
print("#--**字典不定长函数输出--------------------------------------------------------")
# 可写函数说明
def printinfo( arg1, **vardict ): #两个星号 ** 的参数会以字典的形式导入
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vardict)
# 调用printinfo 函数
printinfo(1, a=2,b=3)
print()
print("#--*字典不定长函数输出--------------------------------------------------------")
def f(a,b,*,c): #单独出现星号 * 后的参数必须用关键字传入
return a+b+c
#print(f(1,2,3)) #错误
print(f(1,2,c=3)) #正确
#--*元组不定长函数输出--------------------------------------------------------
输出:
10
()
输出:
70
(60, 50)
#--**字典不定长函数输出--------------------------------------------------------
输出:
1
{'a': 2, 'b': 3}
#--*字典不定长函数输出--------------------------------------------------------
6
5、匿名函数:
(1)定义:
- 所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
(2)语法:
lambda [arg1 [,arg2,.....argn]]:expression
(3)示例:
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
相加后的值为 : 30
相加后的值为 : 40
6、强制位置参数:
(1)定义:
Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。
(2)示例:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
f(10, 20, 30, d=40, e=50, f=60) #形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 或 f 要求为关键字形参
#f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
#sf(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式
10 20 30 40 50 60
三十二、输入和输出:
1、输出格式化:
import math
s = 'Hello, Runoob'
str(s)
print(s)
print()
repr(s)
print(s)
print()
print(str(1/7))
print()
x = 10 * 3.25
y = 200 * 200
s = 'x 的值为: ' + repr(x) + ', y 的值为:' + repr(y) + '...'
print(s)
print()
# repr() 函数可以转义字符串中的特殊字符
hello = 'hello, runoob\n'
hellos = repr(hello)
print(hellos)
# repr() 的参数可以是 Python 的任何对象
print(repr((x, y, ('Google', 'Runoob')))) #函数将对象转化为供解释器读取的形式
print()
for x in range(1, 11):
print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
# 注意前一行 'end' 的使用
print(repr(x*x*x).rjust(4))
print()
for x in range(1, 11):
print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
print()
print('12'.zfill(5)) #在12左侧前5位空缺的地方填充0
print()
print('-3.14'.zfill(7)) #在-3.14左侧前7位空缺的地方填充0
print()
print('3.14159265359'.zfill(5)) #在3.14159265359左侧前5位空缺的地方填充0
print()
print('{}网址: "www.{}"'.format('浮标科技', 'buoy2019.com')) #无下标无键值对,自动下标匹配
print()
print('{0} 和 {1}'.format('Google', 'Runoob')) #下标匹配
print()
print('{1} 和 {0}'.format('Google', 'Runoob')) #下标匹配
print()
print('{name}网址: {site}'.format(name='浮标科技', site='buoy2019.com')) #键值对匹配
print()
print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao')) #下标+键值对匹配
print()
print('常量 PI 的值近似为: {!a}。'.format(math.pi)) #!a (使用 ascii())格式化匹配
print()
print('常量 PI 的值近似为: {!s}。'.format(math.pi)) #!s (使用 str()) 格式化匹配
print()
print('常量 PI 的值近似为: {!r}。'.format(math.pi)) #!r (使用 repr()) 格式化匹配
print()
print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi)) #格式化匹配取小数点后三位
print()
table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
for name, number in table.items():
print('{0:10} ==> {1:10d}'.format(name, number))
print()
table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table)) #格式化键值对下标匹配
print()
print('常量 PI 的值近似为:%5.3f。' % math.pi) #旧式字符串格式化 , % 格式化
print()
Hello, Runoob
Hello, Runoob
0.14285714285714285
x 的值为: 32.5, y 的值为:40000...
'hello, runoob\n'
(32.5, 40000, ('Google', 'Runoob'))
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
00012
-003.14
3.14159265359
浮标科技网址: "www.buoy2019.com"
Google 和 Runoob
Runoob 和 Google
浮标科技网址: buoy2019.com
站点列表 Google, Runoob, 和 Taobao。
常量 PI 的值近似为: 3.141592653589793。
常量 PI 的值近似为: 3.141592653589793。
常量 PI 的值近似为: 3.141592653589793。
常量 PI 的值近似为 3.142。
Google ==> 1
Runoob ==> 2
Taobao ==> 3
Runoob: 2; Google: 1; Taobao: 3
常量 PI 的值近似为:3.142。
三十三、读和写文件:
1、语法:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
opener: 返回调用对象
2、模式:
3、file方法:
4、示例1:(打开并写入内容到文件)
f = open("tmp/foo.txt", "w")
f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
# 关闭打开的文件
f.close()
Python 是一个非常好的语言。
是的,的确非常好!!
5、示例2:(读取文件内容)
# 打开一个文件
f = open("tmp/foo.txt", "r")
str = f.read()
print(str)
# 关闭打开的文件
f.close()
Python 是一个非常好的语言。
是的,的确非常好!!
6、示例3:(文件中读取单独的一行)
# 打开一个文件
f = open("tmp/foo.txt", "r")
str = f.readline()
print(str)
# 关闭打开的文件
f.close()
Python 是一个非常好的语言。
7、示例4:(读取所有行并在一行内显示)
# 打开一个文件
f = open("tmp/foo.txt", "r")
str = f.readlines()
print(str)
# 关闭打开的文件
f.close()
['Python 是一个非常好的语言。\n', '是的,的确非常好!!']
8、示例5:(迭代读取所有行数)
# 打开一个文件
f = open("tmp/foo.txt", "r")
for line in f:
print(line, end='')
# 关闭打开的文件
f.close()
Python 是一个非常好的语言。
是的,的确非常好!!
9、示例6:(记录写入文件的字符数)
# 打开一个文件
f = open("tmp/foo.txt", "w")
num = f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
print(num)
# 关闭打开的文件
f.close()
29
10、示例7:(记录写入文件的非字符串数据)
# 打开一个文件
f = open("tmp/foo.txt", "w")
value = ('www.runoob.com', 14)
s = str(value)
f.write(s)
# 关闭打开的文件
f.close()
('www.runoob.com', 14)
11、示例8:(移动光标写入文件)
# 打开一个文件
f = open("tmp/foo.txt", "rb+")
print("现在一共有" , end = "")
print(f.write(b'0123456789abcdef') , end = "") #读取元素个数
print("元素")
print()
print("现在移动到" , end = "")
print(f.seek(5) + 1 , end = "") #f.seek(5)光标移动到文件的第六个字节 , 移动到5
print("个字节")
print()
print(f.read(1)) #读第七个(因为f.seek(5)光标移动到文件的第六个字节)
print()
print("现在移动到" , end = "")
print(f.seek(-3, 2) , end = "") # 移动到文件的倒数第三字节, 移动到 c
print("个字节")
print()
print(f.read(1)) # 向右读取一个字节
print()
# 关闭打开的文件
f.close() #若关闭已经关闭的文件则报错
现在一共有16元素
现在移动到6个字节
b'5'
现在移动到13个字节
b'd'
12、示例9:(with...as快速打开文件)
with open('tmp/foo.txt' , 'r') as f :
print(f.read())
f.close()
0123456789abcdef
13、示例10:(序列化和反序列化)
#导入序列化包pickle
#导入详细数据结构输出包(包含数据结构输出)pprint
import pickle , pprint
#---序列化------------------------------------------------------------------------
# 使用pickle模块将数据对象(list形式)保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j], #列表
'b': ('string', u'Unicode string'), #元组
'c': None} #变量
selfref_list = [1, 2, 3] #list列表对象
selfref_list.append(selfref_list) #添加列表元素自己本身的内存地址
output = open('data.pkl', 'wb')
# 将data.pkl文件序列化并写入数据data1
pickle.dump(data1, output)
# 将data.pkl文件序列化并写入数据selfref_list
pickle.dump(selfref_list, output, -1)
output.close()
#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')
data1 = pickle.load(pkl_file)
pprint.pprint(data1)
data2 = pickle.load(pkl_file)
pprint.pprint(data2)
pkl_file.close()
{'a': [1, 2.0, 3, (4+6j)], 'b': ('string', 'Unicode string'), 'c': None}
[1, 2, 3, <Recursion on list with id=2237360872768>]
三十四、Python3 OS 文件/目录方法:
1、Python3 OS 文件/目录方法:
三十五、断言(assert):
1、定义:
用于判断一个表达式,在表达式条件为 false 的时候触发异常
2、作用:
在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况
3、语法:
单参数: assert expression
多参数: assert expression [, arguments]
4、示例:
import sys
assert ('linux' in sys.platform), "改代码只能在 Linux 下执行"
Traceback (most recent call last):
File "D:\Python_Src\文件操作\断言\assert.py", line 2, in <module>
assert ('linux' in sys.platform), "改代码只能在 Linux 下执行"
AssertionError: 改代码只能在 Linux 下执行
[Finished in 0.2s with exit code 1]
[shell_cmd: python -u "D:\Python_Src\文件操作\断言\assert.py"]
[dir: D:\Python_Src\文件操作\断言]
[path: D:\Python\Scripts\;D:\Python\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;D:\Java\jdk-13\bin;D:\mysql-cluster-8.0.14-dmr-winx64\bin;D:\mysql-8.0.16-winx64\bin;D:\RabbitAndErlang\rabbitmq_server-3.7.14\sbin;D:\apache-maven-3.6.3\bin;D:\Python;E:\Git\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;]
三十六、异常捕捉:
1、定义:
判断程序语句是否存在逻辑错误
2、作用:
程序语句存在逻辑错误时及时捕捉防止系统资源浪费或更严重结果
3、语法:
单异常捕捉:
try:
# 执行语句
except1 [# 异常类型]:
# 异常处理方式
[
except2 [# 异常类型]:
# 异常处理方式
except3 [# 异常类型]:
# 异常处理方式
except4 [# 异常类型]:
# 异常处理方式
...
exceptn [# 异常类型]:
# 异常处理方式
]
finally
# 最终抛出方式
嵌套异常捕捉:
try:
# 执行语句
except1 [# 异常类型]:
# 嵌套异常捕捉
else:
try:
# 执行语句
except1 [# 异常类型]:
# 异常处理方式
[
except2 [# 异常类型]:
# 异常处理方式
except3 [# 异常类型]:
# 异常处理方式
except4 [# 异常类型]:
# 异常处理方式
...
exceptn [# 异常类型]:
# 异常处理方式
]
finally
# 最终抛出方式
4、示例:
try:
runoob()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('这句话,无论异常是否发生都会执行。')
这句话,无论异常是否发生都会执行。Traceback (most recent call last):
File "D:\Python_Src\文件操作\异常捕捉\ycbz.py", line 2, in <module>
runoob()
NameError: name 'runoob' is not defined
三十七、抛出异常:
1、情景:
在满足条件时即使用 raise 语句抛出一个指定的异常,不必依赖原本定义的异常
2、示例:
x = 10
if x > 5:
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Traceback (most recent call last):
File "D:\Python_Src\文件操作\抛出异常\pcyc.py", line 3, in <module>
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Exception: x 不能大于 5。x 的值为: 10
三十八、用户自定义异常:
1、情景:
定义一个自己需要的异常场景
2、示例1:(用户自定义异常)
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError(2*2)
except MyError as e:
print('My exception occurred, value:', e.value)
My exception occurred, value: 4
3、示例2:(异常场景判断)
class Error(Exception):
"""Base class for exceptions in this module."""
pass # 占位符不做任何操作
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
三十九、预定义清理行为:
1、情景:
触发异常后的默认操作
2、语法:
with #操作 as #变量名:
3、示例:
with open("myfile.txt") as f:
for line in f: #结束后自动执行f.close()
print(line, end="")
四十、面向对象:
1、概念:
(1)类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
(2)方法:类中定义的函数。
(3)类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
(4)数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
(5)方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
(6)局部变量:定义在方法中的变量,只作用于当前实例的类。
(7)实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
(8)继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
(9)实例化:创建一个类的实例,类的具体对象。
(10)对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
2、类定义:
(1)语法:
class ClassName:
<statement-1>
.
.
.
<statement-N>
(2)类构造函数:
# self 指向自己关键字
def __init__(self):
self.data = []
3、类对象:
(1)示例:
class MyClass:
"""一个简单的类实例"""
i = 12345
def f(self):
return 'hello world'
# 实例化类
x = MyClass()
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())
MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world
4、self关键字:
# 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
<__main__.Test object at 0x000001E984BF6940>
<class '__main__.Test'>
5、类的方法:
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁 , %d 公斤。" %(self.name,self.age,self.__weight))
# 实例化类
p = people('runoob',10,30)
p.speak()
runoob 说: 我 10 岁 , 30 公斤。
6、继承:
(1)语法:
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
(2)在另一个模块调用基类:
class DerivedClassName(modname.BaseClassName):
(3)示例:
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
s = student('ken',10,60,3)
s.speak()
ken 说: 我 10 岁了,我在读 3 年级
(4)备注:
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
7、多继承:
(1)示例:
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
#另一个类,多重继承之前的准备
class speaker():
topic = ''
name = ''
def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("Tim",25,80,4,"Python")
test.speak() #方法名同,默认调用的是在括号中排前地父类的方法
我叫 Tim,我是一个演说家,我演讲的主题是 Python
(2)备注:
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
8、方法重写:
(1)示例:
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
调用子类方法
调用父类方法
9、类属性与方法:
(1)概念:
I.类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
II.类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
III.类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
(2)私有变量示例:
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount) # 报错,实例不能访问私有变量
1
2
2
Traceback (most recent call last):
File "D:\Python_Src\文件操作\面向对象\私有变量\sybl.py", line 14, in <module>
print (counter.__secretCount) # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'
(3)私有方法示例:
class Site:
def __init__(self, name, url):
self.name = name # public
self.__url = url # private
def who(self):
print('name : ', self.name)
print('url : ', self.__url)
def __foo(self): # 私有方法
print('这是私有方法')
def foo(self): # 公共方法
print('这是公共方法')
self.__foo()
x = Site('菜鸟教程', 'www.runoob.com')
x.who() # 正常输出
x.foo() # 正常输出
x.__foo() # 报错
Traceback (most recent call last):
name : File "D:\Python_Src\文件操作\面向对象\私有方法\syff.py", line 20, in <module>
菜鸟教程
url : www.runoob.com
这是公共方法
这是私有方法
x.__foo() # 报错
AttributeError: 'Site' object has no attribute '__foo'
10、类的专有方法:
- __init__ : 构造函数,在生成对象时调用
- __del__ : 析构函数,释放对象时使用
- __repr__ : 打印,转换
- __setitem__ : 按照索引赋值
- __getitem__: 按照索引获取值
- __len__: 获得长度
- __cmp__: 比较运算
- __call__: 函数调用
- __add__: 加运算
- __sub__: 减运算
- __mul__: 乘运算
- __truediv__: 除运算
- __mod__: 求余运算
- __pow__: 乘方
11、运算符重载:
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other): #类的专有方法
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
Vector (7, 8)
四十一、Python3 命名空间和作用域:
(1)命名空间定义:
命名空间(Namespace)是从名称到对象的映射
大部分的命名空间都是通过 Python 字典来实现的。
(2)命名空间类型:
- 内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
- 全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
- 局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)。
(3)命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
# var1 是全局名称
var1 = 5
def some_func():
# var2 是局部名称
var2 = 6
def some_inner_func():
# var3 是内嵌的局部名称
var3 = 7
# 生命周期销毁顺序: var3 -> var2 -> var1
(4)作用域定义:
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
(5)作用域类型:
- L(Local):最内层,包含局部变量,比如一个函数/方法内部。
- E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
- G(Global):当前脚本的最外层,比如当前模块的全局变量。
- B(Built-in): 包含了内建的变量/关键字等。,最后被搜索
- 查询顺序:
(6)作用域示例:
import builtins # 内置作用域依赖包
print(dir(builtins)) # 输出内置作用域的参数的属性和参数可执行的方法
g_count = 0 # 全局作用域
def outer():
o_count = 1 # 闭包函数外的函数中
def inner():
i_count = 2 # 局部作用域
# 查找属性 i_count->o_count->g_count->dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,
if True: msg = 'I am from Runoob' print(msg) # 输出为I am from Runoob , 不创建新的作用域
def test(): msg_inner = 'I am from Runoob' print(msg_inner) # 报错 , 外部变量不能引用内部变量 ,函数创建新的作用域
(7)global关键字在局部改变全局变量:(跨命名空间)
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num) # 已在函数fun1()内更改
1
123
123
(8)nonlocal关键字局部改变全局变量:(跨作用域)
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明 , 局部改变全局变量:(跨作用域)
num = 100
print(num)
inner()
print(num)
outer()
100
100
四十二、正则表达式:
1. 起始位置匹配一个模式:
(1)语法:
re.match(pattern, string, flags=0)
(2)示例:
import re
print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配 , span()输出匹配的范围
print(re.match('www', 'www.runoob.com')) # 在起始位置匹配
print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配
line = "Cats are smarter than dogs"
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符 , re.M|re.I 多行匹配(re.M)且
# 使匹配对大小写不敏感(re.I)
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.group() : ", matchObj.group()) # 全文本匹配
print ("matchObj.group(1) : ", matchObj.group(1)) # 第一个正则表达式匹配
print ("matchObj.group(2) : ", matchObj.group(2)) # 第二个正则表达式匹配
else:
print ("No match!!")
(0, 3)
<re.Match object; span=(0, 3), match='www'>
None
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
2. 扫描整个字符串并返回第一个成功的匹配:
(1)语法:
re.search(pattern, string, flags=0)
(2)示例:
import re
print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配 , span()输出匹配的范围
print(re.search('www', 'www.runoob.com')) # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配 , span()输出匹配的范围
print(re.search('com', 'www.runoob.com')) # 不在起始位置匹配
line = "Cats are smarter than dogs";
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符 , re.M|re.I 多行匹配(re.M)且
# 使匹配对大小写不敏感(re.I)
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
if searchObj:
print ("searchObj.group() : ", searchObj.group()) # 全文本匹配
print ("searchObj.group(1) : ", searchObj.group(1)) # 第一个正则表达式匹配
print ("searchObj.group(2) : ", searchObj.group(2)) # 第二个正则表达式匹配
else:
print ("Nothing found!!")
(0, 3)
<re.Match object; span=(0, 3), match='www'>
(11, 14)
<re.Match object; span=(11, 14), match='com'>
searchObj.group() : Cats are smarter than dogs
searchObj.group(1) : Cats
searchObj.group(2) : smarter
3. re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print ("match --> matchObj.group() : ", matchObj.group()) else: print ("No match!!") matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print ("search --> matchObj.group() : ", matchObj.group()) else: print ("No match!!")
No match!! search --> matchObj.group() : dogs
4. 检索和替换:
1. 替换字符串中的匹配项:
(1)语法:
re.sub(pattern, repl, string, count=0, flags=0)
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。[可选]
flags : 编译时用的匹配模式,数字形式。[可选]
(2)示例:
import re
print("#--查找并替换字符串------------------------------------------------------------")
phone = "2004-959-559 # 这是一个电话号码"
# 删除注释
num = re.sub(r'#.*$', "", phone)
print ("电话号码 : ", num)
# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print ("电话号码 : ", num)
print("#--查找并替换函数------------------------------------------------------------")
# 将匹配的数字乘于 2
def double(matched):
value = int(matched.group('value'))
return str(value * 2)
s = 'A23G4HFD567'
# (1)调用?P<>模式匹配函数double中的group('value')
# (2)\d+匹配多个数字部分(若是\d则每个独立匹配拼接)
print(re.sub('(?P<value>\d+)', double, s))
#--查找并替换字符串------------------------------------------------------------
电话号码 : 2004-959-559
电话号码 : 2004959559
#--查找并替换函数------------------------------------------------------------
A46G8HFD1134
2. 生成一个正则表达式( Pattern )对象:
(1)语法:
re.compile(pattern[, flags])
pattern : 一个字符串形式的正则表达式
flags 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为' . '并且包括换行符在内的任意字符(' . '不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和' # '后面的注释
(2)示例:
import re
pattern = re.compile(r'\d+') # 用于匹配至少一个数字
m = pattern.match('one12twothree34four') # 查找头部,没有匹配
print("从头部开始匹配:",m)
m = pattern.match('one12twothree34four', 2 , 10) # 从'e'的位置开始匹配,没有匹配 , 10 表示标志位有没有都一样
print("从2到9开始匹配:",m)
m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配 , 10 表示标志位有没有都一样
print("从3到9开始匹配:(输出全段)",m) # 返回一个 Match 对象
print("从3到9开始匹配:(输出匹配数)",m.group(0)) # 可省略 0 , 显示匹配的字符串
print("返回开始匹配下标",m.start(0)) # 可省略 0 , 显示开始匹配的位置
print("返回结束匹配下标",m.end(0)) # 可省略 0 , 显示结束匹配的位置
print("返回匹配字符串区间(左闭右开)",m.span(0)) # 可省略 0 , 显示匹配的字符串区间(左闭右开)
pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小写
m = pattern.match('Hello World Wide Web')
print(m) # 匹配成功,返回一个 Match 对象
print(m.group(0)) # 返回匹配成功的整个子串
print(m.span(0)) # 返回匹配成功的整个子串的索引
print(m.group(1)) # 返回第一个分组匹配成功的子串
print(m.span(1)) # 返回第一个分组匹配成功的子串的索引
print(m.group(2)) # 返回第二个分组匹配成功的子串
print(m.span(2)) # 返回第二个分组匹配成功的子串索引
print(m.groups()) # 等价于 (m.group(1), m.group(2), ...)
#print(m.group(3)) # 不存在第三个分组 , 报错
从头部开始匹配: None
从2到9开始匹配: None
从3到9开始匹配:(输出全段) <re.Match object; span=(3, 5), match='12'>
从3到9开始匹配:(输出匹配数) 12
返回开始匹配下标 3
返回结束匹配下标 5
返回匹配字符串区间(左闭右开) (3, 5)
<re.Match object; span=(0, 11), match='Hello World'>
Hello World
(0, 11)
Hello
(0, 5)
World
(6, 11)
('Hello', 'World')
3. 字符串中找到正则表达式所匹配的所有子串:
(1)语法:
re.findall(string[, pos[, endpos]])
string 待匹配的字符串。
pos 可选参数,指定字符串的起始位置,默认为 0。
endpos 可选参数,指定字符串的结束位置,默认为字符串的长度。
(2)示例:
import re
pattern = re.compile(r'\d+') # 查找数字
result1 = pattern.findall('runoob 123 google 456') # 不写就是全文匹配 ,只写0也是全文匹配
result2 = pattern.findall('run88oob123google456', 0, 10) # 下标0~9字符串匹配
print(result1)
print(result2)
['123', '456']
['88', '12']
4. 在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回:
(1)语法:
re.finditer(pattern, string, flags=0)
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
(2)示例:
import re
it = re.finditer(r"\d+","12a32bc43jf3") #匹配数字 , 无标志位
for match in it:
print (match.group() )
12
32
43
3
5. 按照能够匹配的子串将字符串分割后返回列表:
(1)语法:
re.split(pattern, string[, maxsplit=0, flags=0])
pattern 匹配的正则表达式
string 要匹配的字符串
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数
flags 标志位,用于控制正则表达式的匹配方式
(2)示例:
import re
print("匹配使用非数字的部分: ",re.split('\W+', 'runoob, runoob, runoob.')) # 匹配使用非数字的部分
print("匹配括号内的表达式非数字的部分(详细分隔): ",re.split('(\W+)', ' runoob, runoob, runoob.')) # 匹配括号内的表达式非数字的部分
print("匹配使用非数字的部分 , 分隔1次: ",re.split('\W+', ' runoob, runoob, runoob.', 1)) # 匹配使用非数字的部分 , 分隔1次
print("对于一个找不到匹配的字符串而言,split 全分割: ",re.split('a*', 'hello world')) # 对于一个找不到匹配的字符串而言,split 全分割
匹配使用非数字的部分: ['runoob', 'runoob', 'runoob', '']
匹配括号内的表达式非数字的部分(详细分隔): ['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
匹配使用非数字的部分 , 分隔1次: ['', 'runoob, runoob, runoob.']
对于一个找不到匹配的字符串而言,split 全分割: ['', 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '']
6. 正则表达式对象:
re.RegexObject
re.compile() 返回 RegexObject 对象。
re.MatchObject
group() 返回被 RE 匹配的字符串。
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置
7. 正则表达式修饰符 - 可选标志:
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
8. 正则表达式模式:
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n} 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
re{ n,} 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b 匹配a或b
(re) 匹配括号内的表达式,也表示一个组
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (...), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释.
(?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re) 匹配的独立模式,省去回溯。
\w 匹配数字字母下划线
\W 匹配非数字字母下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f]。
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9]。
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。 匹配一个换行符。匹配一个制表符, 等
\1...\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
9. 正则表达式实例:
字符匹配
python 匹配 "python".
字符类
实例 描述
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符
特殊字符类
实例 描述
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
四十三、网络编程:
1. 定义:
应用程序使用套接字(Socket)向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯
2. 类型:
低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
3. 语法:
socket.socket([family[, type[, proto]]])
family: 套接字家族可以使AF_UNIX(管道通信,同类主机通信)或者AF_INET(TCP/IP,可非同类主机通信)
type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM(TCP连接)或SOCK_DGRAM(UDP连接)
protocol: 一般不填默认为0.
4. 方法:
函数 | 描述 |
---|---|
服务器端套接字:s | |
s.bind() | 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字 | |
s.connect() | 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
s.connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数 | |
s.recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
s.sendall() | 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvfrom() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字 |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 |
s.makefile() | 创建一个与该套接字相关连的文件 |
5. 示例:
服务端:
# 导入 socket
import socket
# 创建 socket 对象
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# 获取本地主机名
host = socket.gethostname()
port = 9999
# 绑定地址
serversocket.bind((host, port))
# 监听请求,设置最大连接数,超过后排队
serversocket.listen(5)
while True:
# 建立客户端连接
clientsocket,addr = serversocket.accept()
print("连接地址: %s" % str(addr))
msg='欢迎访问浮标科技!'+ "\r\n"
clientsocket.send(msg.encode('utf-8')) # 设置字符编码为utf-8
clientsocket.close() # 关闭套接字
客户端:
# 导入 socket
import socket
# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取本地主机名
host = socket.gethostname()
# 设置端口号
port = 9999
# 连接服务,指定主机和端口
s.connect((host, port))
# 接收小于 1024 字节的数据 , 可不写无限制
msg = s.recv(1024)
s.close()
print (msg.decode('utf-8'))
输出结果:
欢迎访问浮标科技!
6、其他网络接口包:
协议 | 功能用处 | 端口号 | Python 模块 |
---|---|---|---|
HTTP | 网页访问 | 80 | httplib, urllib, xmlrpclib |
NNTP | 阅读和张贴新闻文章,俗称为"帖子" | 119 | nntplib |
FTP | 文件传输 | 20 | ftplib, urllib |
SMTP | 发送邮件 | 25 | smtplib |
POP3 | 接收邮件 | 110 | poplib |
IMAP4 | 获取邮件 | 143 | imaplib |
Telnet | 命令行 | 23 | telnetlib |
Gopher | 信息查找 | 70 | gopherlib, urllib |
四十四、SMTP编程:
(1)语法:
# 创建SMTP 邮件发送对象
import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
"""
host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:runoob.com,这个是可选参数。
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下SMTP端口号为25。
local_hostname: 如果SMTP在你的本机上,你只需要指定服务器地址为 localhost 即可。
"""
# 使用SMTP对象发送邮件
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]
"""
from_addr: 邮件发送者地址。
to_addrs: 字符串列表,邮件发送地址。
msg: 发送消息(必须是SMTP格式,必须包括标题,发信人,收件人,邮件内容)
"""
(2)示例1:(使用第三方 SMTP 服务发送)
1. 申请第三方SMTP服务:
(3)示例2:(使用Python发送HTML格式的邮件)
(4)示例3:(Python 发送带附件的邮件)
(5)示例4:(在 HTML 文本中添加图片)
四十五、JSON 格式解析:
(1)JSON 与 Python3 数据类型对应表:
1. Python 编码为 JSON 类型转换对应表:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int- & float-derived Enums | number |
True | true |
False | false |
None | null |
2. JSON 解码为 Python 类型转换对应表:
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
(2)JSON编码与转码示例:
import json
# Python 字典类型转换为 JSON 对象
data = {
'no' : 1,
'name' : 'buoy2019',
'url' : 'http://www.buoy2019.com'
}
json_str = json.dumps(data) # 对python 字典型数据进行JSON编码
print ("Python 原始数据:", repr(data))
print ("JSON 对象:", json_str)
data2 = json.loads(json_str) # 将 JSON 对象转换为 Python 字典
print ("data2['no']: ", data2['no'])
print ("data2['name']: ", data2['name'])
print ("data2['url']: ", data2['url'])
# 写入 JSON 数据
# data.json 写入JSON数据的文件
# w 写入模式
# f 文件流操作对象
with open('data.json', 'w') as f:
# data 写入文件的数据
# f 写入的文件对象
json.dump(data, f)
# 读取数据
with open('data.json', 'r') as f:
#print("读取文件中的JSON数据:",f.read())
data = json.load(f)
print("读取文件中的JSON数据并转化为Python 字典格式:",data)
四十六、XML格式解析:
(1)解析方法:
1.SAX (simple API for XML )
Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
1. 基于事件驱动的API 2. 依赖: (1)解析器: I. 负责读取 XML 文档,并向事件处理器发送事件,如元素开始跟元素结束事件 (2)事件处理器: II. 事件作出响应,对传递的 XML 数据进行处理 (I)对大型文件进行处理。 (II)只需要文件的部分内容,或者只需从文件中得到特定信息。 (III)建立自己的对象模型的时候。
2.DOM(Document Object Model)
将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。
(2)示例XML:
<collection shelf="New Arrivals">
<movie title="Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
(3)SAX解析:
import xml.sax
# 定义SAX解析类
class MovieHandler( xml.sax.ContentHandler ):
# 定义构造函数匹配对应标签值
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# 元素开始调用
def startElement(self, tag, attributes):
# 匹配title标签标志是否为movie , 匹配成功输出其title值
self.CurrentData = tag
if tag == "movie":
print ("*****Movie*****")
title = attributes["title"]
print ("Title:", title)
# 读取字符时调用
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
# 元素结束调用
def endElement(self, tag):
if self.CurrentData == "type":
print ("Type:", self.type)
elif self.CurrentData == "format":
print ("Format:", self.format)
elif self.CurrentData == "year":
print ("Year:", self.year)
elif self.CurrentData == "rating":
print ("Rating:", self.rating)
elif self.CurrentData == "stars":
print ("Stars:", self.stars)
elif self.CurrentData == "description":
print ("Description:", self.description)
self.CurrentData = ""
# 假如是主线程就执行
if ( __name__ == "__main__"):
# 创建一个 XMLReader
# xml.sax.make_parser( [parser_list] )
# parser_list - 可选参数,解析器列表
parser = xml.sax.make_parser()
# 关闭命名空间
#parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 重写 ContextHandler
Handler = MovieHandler()
parser.setContentHandler( Handler )
# 匹配xml文件
# xml.sax.parse( xmlfile, contenthandler[, errorhandler])
# xmlfile - xml文件名
# contenthandler - 必须是一个 ContentHandler 的对象
# errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler 对象
parser.parse("movies.xml")
# parseString 方法创建一个 XML 解析器并解析 xml 字符串
# xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
# xmlstring - xml字符串
# contenthandler - 必须是一个 ContentHandler 的对象
# errorhandler - 如果指定该参数,errorhandler 必须是一个 SAX ErrorHandler对象
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom
(4)DOM解析:
from xml.dom.minidom import parse
import xml.dom.minidom
# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movies.xml")
# 赋值
collection = DOMTree.documentElement
# 匹配DOM树元素
if collection.hasAttribute("shelf"):
print ("Root element : %s" % collection.getAttribute("shelf"))
# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")
# 打印每部电影的详细信息
for movie in movies:
print ("*****Movie*****")
if movie.hasAttribute("title"):
print ("Title: %s" % movie.getAttribute("title"))
type = movie.getElementsByTagName('type')[0]
print ("Type: %s" % type.childNodes[0].data)
format = movie.getElementsByTagName('format')[0]
print ("Format: %s" % format.childNodes[0].data)
rating = movie.getElementsByTagName('rating')[0]
print ("Rating: %s" % rating.childNodes[0].data)
stars = movie.getElementsByTagName('stars')[0]
print("stars: %s" % stars.childNodes[0].data)
description = movie.getElementsByTagName('description')[0]
print ("Description: %s" % description.childNodes[0].data)
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
stars: 2
Description: Viewable boredom
四十七、多线程:
(1)定义:
线程是资源调配的最小单位
线程可以分为:
(1)内核线程:由操作系统内核创建和撤销。
(2)用户线程:不需要内核支持而在用户程序中实现的线程。
(2)创建线程:
1. 语法:
_thread.start_new_thread ( function, args[, kwargs] )
"""
function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple(元组)类型。
kwargs - 可选参数。
"""
2. 示例1(_thread创建线程,不推荐使用):
import _thread
import time
# 为线程定义一个函数
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
# 创建两个线程
try:
_thread.start_new_thread( print_time,("Thread-1", 2, ) )
_thread.start_new_thread( print_time,("Thread-2", 4, ) )
except:
print ("Error: 无法启动线程")
# 保持线程启动状态
while 1:
pass
Thread-1: Wed Jan 15 16:11:15 2020
Thread-2: Wed Jan 15 16:11:17 2020
Thread-1: Wed Jan 15 16:11:17 2020
Thread-1: Wed Jan 15 16:11:19 2020
Thread-2: Wed Jan 15 16:11:21 2020
Thread-1: Wed Jan 15 16:11:21 2020
Thread-1: Wed Jan 15 16:11:23 2020
Thread-2: Wed Jan 15 16:11:25 2020
Thread-2: Wed Jan 15 16:11:29 2020
Thread-2: Wed Jan 15 16:11:33 2020
2. 示例2(使用 threading 模块创建线程,推荐使用):
import threading
import time
print ("使用 threading 模块创建线程:")
exitFlag = 0
class myThread (threading.Thread):
# 初始化线程构造方法
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("开始线程:" + self.name)
print_time(self.name, self.counter, 5)
print ("退出线程:" + self.name)
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")
"""
线程信息方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。
正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
线程运行生命周期方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。
这阻塞调用线程直至线程的join() 方法被调用中止-正常退出
或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
"""
使用 threading 模块创建线程:
开始线程:Thread-1
开始线程:Thread-2
Thread-1: Wed Jan 15 16:27:58 2020
Thread-2: Wed Jan 15 16:27:59 2020
Thread-1: Wed Jan 15 16:27:59 2020
Thread-1: Wed Jan 15 16:28:00 2020
Thread-2: Wed Jan 15 16:28:01 2020
Thread-1: Wed Jan 15 16:28:01 2020
Thread-1: Wed Jan 15 16:28:02 2020
退出线程:Thread-1
Thread-2: Wed Jan 15 16:28:03 2020
Thread-2: Wed Jan 15 16:28:05 2020
Thread-2: Wed Jan 15 16:28:07 2020
退出线程:Thread-2
退出主线程
(3)线程同步:
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("开启线程: " + self.name)
# 获取锁,用于线程同步
threadLock.acquire()
print_time(self.name, self.counter, 3)
# 释放锁,开启下一个线程
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
threadLock = threading.Lock()
threads = []
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有线程完成
for t in threads:
t.join()
print ("退出主线程")
开启线程: Thread-1
开启线程: Thread-2
Thread-1: Wed Jan 15 16:41:20 2020
Thread-1: Wed Jan 15 16:41:21 2020
Thread-1: Wed Jan 15 16:41:22 2020
Thread-2: Wed Jan 15 16:41:24 2020
Thread-2: Wed Jan 15 16:41:26 2020
Thread-2: Wed Jan 15 16:41:28 2020
退出主线程
(4)线程优先级队列:
import queue
import threading
import time
"""
该程序无线程安全
"""
"""
Python 的 Queue 模块中提供了同步的、线程安全的队列类,
包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,
和优先级队列 PriorityQueue。
这些队列都实现了锁原语,能够在多线程中直接使用,
可以使用队列来实现线程间的同步。
Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,
Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
"""
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print ("开启线程:" + self.name)
process_data(self.name, self.q)
print ("退出线程:" + self.name)
# 定义进程数据方法
def process_data(threadName, q):
while not exitFlag:
#获取锁,用于线程同步
queueLock.acquire()
# Queue.empty()如果队列为空,返回True,反之False
# if not workQueue.empty() 如果队列不为空
if not workQueue.empty():
# 获取队列
data = q.get()
# 释放锁,开启下一个线程
queueLock.release()
print ("%s processing %s" % (threadName, data))
else:
# 释放锁,开启下一个线程
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
# 获得队列锁
queueLock = threading.Lock()
# 定义队列大小
workQueue = queue.Queue(10)
# 定义线程组
threads = []
# 定义线程ID
threadID = 1
# 创建新线程
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# 获取锁,用于线程同步
queueLock.acquire()
# 填充队列
for word in nameList:
workQueue.put(word)
# 释放锁,开启下一个线程
queueLock.release()
# 等待队列清空
while not workQueue.empty():
pass
# 通知线程是时候退出
exitFlag = 1
# 等待所有线程完成
for t in threads:
t.join()
print ("退出主线程")
开启线程:Thread-1
开启线程:Thread-2
开启线程:Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
退出线程:Thread-2
退出线程:Thread-3
退出线程:Thread-1
退出主线程
四十八、内置函数:
四十九、日期和时间:
(1)时间戳:
import time # 引入time模块
ticks = time.time()
print ("当前时间戳为:", ticks)
当前时间戳为: 1579429080.8330948
(2)获取当前时间:
import time
localtime = time.localtime(time.time())
# 元组形式
print ("本地时间为(宿主机) :", localtime)
"""
序号 属性 值
0 tm_year 2008
1 tm_mon 1 到 12
2 tm_mday 1 到 31
3 tm_hour 0 到 23
4 tm_min 0 到 59
5 tm_sec 0 到 61 (60或61 是闰秒)
6 tm_wday 0到6 (0是周一)
7 tm_yday 一年中的第几天,1 到 366
8 tm_isdst 是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1
"""
本地时间为 : time.struct_time(tm_year=2020, tm_mon=1, tm_mday=19, tm_hour=18, tm_min=19, tm_sec=43, tm_wday=6, tm_yday=19, tm_isdst=0)
(3)获取格式化的时间:
import time
# 格式化语法:
# time.strftime(format[, t])
# format 格式化格式
# t 日期函数
# 格式化成 Sun Jan 19 18:38:57 2020
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
# 格式化成 Sun Jan 19 18:38:57 2020形式
print (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
# 将格式字符串转换为时间戳
a = "Sun Jan 19 18:38:57 2020"
print (time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))
"""
python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
"""
2020-01-19 18:39:51
Sun Jan 19 18:39:51 2020
1579430337.0
(4)获取某月日历:
import calendar
cal = calendar.month(2020, 1)
print ("以下输出2020年1月份的日历:")
print (cal)
以下输出2020年1月份的日历:
January 2020
Mo Tu We Th Fr Sa Su
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
(5)Time 模块内置函数:
序号 | 函数及描述 | 实例 |
---|---|---|
1 | time.altzone 返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。 | 以下实例展示了 altzone()函数的使用方法: |
2 | time.asctime([tupletime]) 接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。 | 以下实例展示了 asctime()函数的使用方法: |
3 | time.clock() 用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。 | 由于该方法依赖操作系统,在 Python 3.3 以后不被推荐,而在 3.8 版本中被移除,需使用下列两个函数替代。 |
4 | time.ctime([secs]) 作用相当于asctime(localtime(secs)),未给参数相当于asctime() | 以下实例展示了 ctime()函数的使用方法: |
5 | time.gmtime([secs]) 接收时间戳(1970纪元后经过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0 | 以下实例展示了 gmtime()函数的使用方法: |
6 | time.localtime([secs] 接收时间戳(1970纪元后经过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是不是夏令时)。 | 以下实例展示了 localtime()函数的使用方法: |
7 | time.mktime(tupletime) 接受时间元组并返回时间戳(1970纪元后经过的浮点秒数)。 | 实例 |
8 | time.sleep(secs) 推迟调用线程的运行,secs指秒数。 | 以下实例展示了 sleep()函数的使用方法: |
9 | time.strftime(fmt[,tupletime]) 接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。 | 以下实例展示了 strftime()函数的使用方法: |
10 | time.strptime(str,fmt='%a %b %d %H:%M:%S %Y') 根据fmt的格式把一个时间字符串解析为时间元组。 | 以下实例展示了 strptime()函数的使用方法: |
11 | time.time( ) 返回当前时间的时间戳(1970纪元后经过的浮点秒数)。 | 以下实例展示了 time()函数的使用方法: |
12 | time.tzset() 根据环境变量TZ重新初始化时间相关设置。 | 实例 |
13 | time.perf_counter() 返回计时器的精准时间(系统的运行时间),包含整个系统的睡眠时间。由于返回值的基准点是未定义的,所以,只有连续调用的结果之间的差才是有效的。 | 实例 |
14 | time.process_time() 返回当前进程执行 CPU 的时间总和,不包含睡眠时间。由于返回值的基准点是未定义的,所以,只有连续调用的结果之间的差才是有效的。 |
Time模块包含了以下2个非常重要的属性:
序号 | 属性及描述 |
---|---|
1 | time.timezone 属性time.timezone是当地时区(未启动夏令时)距离格林威治的偏移秒数(>0,美洲;<=0大部分欧洲,亚洲,非洲)。 |
2 | time.tzname 属性time.tzname包含一对根据情况的不同而不同的字符串,分别是带夏令时的本地时区名称,和不带的。 |
(6)日历(Calendar)模块内置函数:
此模块的函数都是日历相关的,例如打印某月的字符月历。
星期一是默认的每周第一天,星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday()函数。模块包含了以下内置函数:
序号 | 函数及描述 |
---|---|
1 | calendar.calendar(year,w=2,l=1,c=6) 返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。 |
2 | calendar.firstweekday( ) 返回当前每周起始日期的设置。默认情况下,首次载入caendar模块时返回0,即星期一。 |
3 | calendar.isleap(year) 是闰年返回 True,否则为 false。 |
4 | calendar.leapdays(y1,y2) 返回在Y1,Y2两年之间的闰年总数。 |
5 | calendar.month(year,month,w=2,l=1) 返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。 |
6 | calendar.monthcalendar(year,month) 返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示,从1开始。 |
7 | calendar.monthrange(year,month) 返回两个整数。第一个是该月的星期几,第二个是该月有几天。星期几是从0(星期一)到 6(星期日)。 (5, 30)解释:5 表示 2014 年 11 月份的第一天是周六,30 表示 2014 年 11 月份总共有 30 天。 |
8 | calendar.prcal(year,w=2,l=1,c=6) 相当于 print calendar.calendar(year,w,l,c). |
9 | calendar.prmonth(year,month,w=2,l=1) 相当于 print calendar.calendar(year,w,l,c)。 |
10 | calendar.setfirstweekday(weekday) 设置每周的起始日期码。0(星期一)到6(星期日)。 |
11 | calendar.timegm(tupletime) 和time.gmtime相反:接受一个时间元组形式,返回该时刻的时间戳(1970纪元后经过的浮点秒数)。 |
12 | calendar.weekday(year,month,day) 返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。 |
五十、CGI(公共网关接口,Windows) 编程 :
(1)下载Apache:
在官网下载Apache,版本为Apache 2.4.26 x64,下载64位的
地址为:http://www.apachehaus.com/cgi-bin/download.plx
(2)配置httpd.conf文件:
1. 打开httpd.conf文件:
2. 修改https.conf文件:
# 步骤1:设置Appache在你电脑的安装目录
Define SRVROOT "D:/httpd-2.4.41-o111c-x64-vc15-r2/Apache24"
ServerRoot "${SRVROOT}"
# 此处若为分布式可以修改为监听主机地址
#Listen 12.34.56.78:80
# 步骤2: 修改监听端口
Listen 2020
# 步骤3. 开启基于主机的组授权(去掉下面这行的注释即可)
LoadModule access_compat_module modules/mod_access_compat.so
# 步骤4. 开启apache的代理模块(直接去掉前面的注释即可)
LoadModule proxy_module modules/mod_proxy.so
# 步骤5. 开启代理http和https请求(直接去掉前面的注释即可)
LoadModule proxy_http_module modules/mod_proxy_http.so
# 步骤6. 开启rewrite模式(直接去掉前面的注释即可)
LoadModule rewrite_module modules/mod_rewrite.so
# 步骤7. 开启虚拟主机动态配置(直接去掉前面的#注释即可)
LoadModule vhost_alias_module modules/mod_vhost_alias.so
# 步骤8. 开启CGI路径的访问权限
<Directory "D:/httpd-2.4.41-o111c-x64-vc15-r2/Apache24/cgi-bin">
AllowOverride All
Options +ExecCGI
Order allow,deny
Allow from all
</Directory>
# 步骤9. 修改映射地址
ScriptAlias /cgi-bin/ "D:/var/www/cgi-bin/"
# 步骤10. 添加后缀
AddHandler cgi-script .cgi .pl .py
# 步骤11. 开启虚拟主机配置
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
3. 启动服务:
cmd 到 bin文件夹 ,输入 httpd -k install -n "Apache2.4"
启动Apache
启动:httpd.exe -w -n "Apache2.4" -k start
停止:httpd.exe -w -n "Apache2.4" -k stop
重启:httpd.exe -w -n "Apache2.4" -k restart
浏览器输入 http://localhost:2020/
显示下图则代表成功配置
五十一、Python连接MySQL(mysql-connector 驱动):
(1)pip安装mysql-connector:
打开控制台输入
python -m pip install mysql-connector
在.py文件中输入
import mysql.connector
运行成功则表示安装成功
(2)创建数据库表:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost", # 数据库主机地址
user="root", # 数据库用户名
passwd="root" # 数据库密码
)
mycursor = mydb.cursor()
# 判断数据库是否存在
# 该语句显示所有数据库名
mycursor.execute("SHOW DATABASES")
# 递归显示数据库名元组
for x in mycursor:
print("数据库: ",x)
# 判断数据库是否存在不存在则创建存在则不执行
mycursor.execute("CREATE DATABASE IF NOT EXISTS jjchoi_db")
# 连接数据库
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
# 执行数据库语句
mycursor = mydb.cursor()
# 判断数据库表是否存在不存在则创建存在则不执行
mycursor.execute("CREATE TABLE IF NOT EXISTS sites (name VARCHAR(255), url VARCHAR(255))")
# 显示数据库表元组
mycursor.execute("SHOW TABLES")
# 输出数据库表元组
for x in mycursor:
print("数据库表: ",x)
# 新添列ID为主键且自动递增
mycursor.execute("ALTER TABLE sites ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY")
# 设置name为主键
#mycursor.execute(" ALTER TABLE sites ADD PRIMARY KEY ( name ); ")
(3)插入数据:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
mycursor = mydb.cursor()
sql = "INSERT INTO sites (name, url) VALUES (%s, %s)"
val = ("JJ-Choi", "https://www.buoy2019.com")
mycursor.execute(sql, val)
mydb.commit() # 数据表内容有更新,必须使用到该语句
print(mycursor.rowcount, "记录插入成功。")
批量插入:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
mycursor = mydb.cursor()
sql = "INSERT INTO sites (name, url) VALUES (%s, %s)"
val = [
('Google', 'https://www.google.com'),
('Github', 'https://www.github.com'),
('Taobao', 'https://www.taobao.com'),
('stackoverflow', 'https://www.stackoverflow.com/')
]
mycursor.executemany(sql, val)
mydb.commit() # 数据表内容有更新,必须使用到该语句
print(mycursor.rowcount, "记录插入成功。")
(4)查询数据:
import mysql.connector
# 文件名不能为select
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM sites")
myresult = mycursor.fetchall() # fetchall() 获取所有记录
for x in myresult:
print("查询数据: ",x)
mycursor.execute("SELECT name, url FROM sites")
myresult = mycursor.fetchall()
for x in myresult:
print("条件查询: ",x)
mycursor.execute("SELECT * FROM sites WHERE name ='RUNOOB'")
myresult = mycursor.fetchall()
for x in myresult:
print("条件查询name ='RUNOOB': ",x)
sql = "SELECT * FROM sites WHERE url LIKE '%oo%'"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print("条件查询WHERE url LIKE '%oo%': ",x)
sql = "SELECT * FROM sites WHERE name = %s"
na = ("RUNOOB", )
mycursor.execute(sql, na)
myresult = mycursor.fetchall()
for x in myresult:
print("防止SQL注入攻击: ",x)
sql = "SELECT * FROM sites ORDER BY name"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print("默认升序排序查询: ",x)
sql = "SELECT * FROM sites ORDER BY name DESC"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print("降序排序查询: ",x)
mycursor.execute("SELECT * FROM sites LIMIT 3")
myresult = mycursor.fetchall()
for x in myresult:
print("限制查询3条: ",x)
mycursor.execute("SELECT * FROM sites LIMIT 3 OFFSET 1") # 0 为 第一条,1 为第二条,以此类推
myresult = mycursor.fetchall()
for x in myresult:
print("从第二条开始查询3条: ",x)
mycursor.execute("SELECT * FROM sites")
myresult = mycursor.fetchone()
# 单独输出执行结束
print("只查询一条: ",myresult)
(5)更新数据:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
mycursor = mydb.cursor()
sql = "UPDATE sites SET name = 'ZH' WHERE name = 'JJ-Choi'"
mycursor.execute(sql)
mydb.commit()
print(mycursor.rowcount, " 条记录被修改")
# 防止SQL注入攻击
sql = "UPDATE sites SET name = %s WHERE name = %s"
val = ("JJ-Choi", "ZH")
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, " 条记录被修改")
(6)删除数据:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="root",
database="jjchoi_db"
)
mycursor = mydb.cursor()
# 该语句线程安全
sql = "DELETE FROM sites WHERE name = 'stackoverflow'"
mycursor.execute(sql)
mydb.commit()
print(mycursor.rowcount, " 条记录删除")
# 防止SQL注入
sql = "DELETE FROM sites WHERE name = %s"
na = ("stackoverflow", )
mycursor.execute(sql, na)
mydb.commit()
print(mycursor.rowcount, " 条记录删除")
# 关闭数据库
mydb.close()
备注:MySQL 8.x 密码问题解决方案
Python MySQL8.0 错误:authentication plugin 'calling_sha2_password' is not supported.
五十二、Python连接MySQL(PyMySQL):
(1)连接数据库:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL 查询
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取单条数据,获取sql版本号.
data = cursor.fetchone()
print ("数据库版本号 : %s " % data)
# 使用预处理语句创建表
sql = """CREATE TABLE IF NOT EXISTS EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
print("数据库表创建成功!")
# 关闭数据库连接
db.close()
(2)插入数据:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
print("插入数据成功!")
except:
# 如果发生错误则回滚
db.rollback()
print("插入数据失败!")
# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ('%s', '%s', %s, '%s', %s)" % \
('Mac', 'Mohan', 20, 'M', 2000)
try:
# 执行sql语句
cursor.execute(sql)
# 执行sql语句
db.commit()
print("占位符插入数据成功!")
except:
# 发生错误时回滚
db.rollback()
print("占位符插入数据失败!")
# 关闭数据库连接
db.close()
(3)查询数据:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > %s" % (1000)
try:
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# 打印结果
print("查询结果:\n","fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \
(fname, lname, age, sex, income ))
except:
print ("查询失败: 没有该数据")
# 关闭数据库连接
db.close()
(4)更改数据:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
# 执行SQL语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
print("更新完成!")
except:
# 发生错误时回滚
db.rollback()
print("更新失败!")
# 关闭数据库连接
db.close()
(5)删除数据:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
# 执行SQL语句
cursor.execute(sql)
# 提交修改
db.commit()
print("删除数据成功!")
except:
# 发生错误时回滚
db.rollback()
print("删除数据成功!")
# 关闭连接
db.close()
(6)执行事务:
import pymysql
# 打开数据库连接
db = pymysql.connect("localhost","root","root","jjchoi_db" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
# 执行SQL语句
cursor.execute(sql)
# 向数据库提交
db.commit()
print("执行事务成功!")
except:
# 发生错误时回滚
db.rollback()
print("执行事务失败!")
五十三、Python3 爬虫:
(1)安装 Requests 第三方库:
pip install requests
(2)安装BeautifulSoup:
pip install BeautifulSoup lxml