Python学习

Python作为我学习的第三门语言,感觉它与Java还是有些相似之处,所以3天内学完Python对我来说还可以接受,关键是读写文件那里还是有些许不懂的地方。之所以学习Python,是因为我们专业开了一门机器学习的课,老师要求用Python编写程序,另一门课也涉及到爬虫之类。

1. print函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#输出数字
print(520)
print(22.22)

#输出字符串
print('hello world')
print("v5le0n9")

#输出含有运算符的表达式
print(520+22.22)

#将数据输出到文件中
fp = open('D:/text.txt', 'a+')
print('hello world', file=fp)
fp.close()

#不进行换行输出
print('hello', 'world', 'Python')

2. 转义字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
print('hello\nv5le0n9')		#换行
print('hello\tv5le0n9') #Tab键,4个一组
print('helloooo\tv5le0n9')
print('hello\rv5le0n9') #光标回到初始位置
print('hello\bv5le0n9') #退格,回退一个字符
print('hello\\tv5le0n9') #输出反斜杠
print('hello\'v5le0n9') #输出单引号
print(r'hello\nv5le0n9') #原样输出

'''
hello
v5le0n9
hello v5le0n9
helloooo v5le0n9
v5le0n9
hellv5le0n9
hello\tv5le0n9
hello'v5le0n9
hello\nv5le0n9
'''

3. 字符编码与关键字

1
2
print(chr(0b100111001011000))#输出字符“乘”,chr编码转字符
print(ord('乘'))#输出十进制20056,ord字符转编码

关键字不能作为标识符使用:

1
2
3
4
5
import keyword
print(keyword.kwlist)
'''
['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']
'''

4. 变量

1
2
3
4
5
6
7
8
9
10
11
name = 'v5le0n9'
print(name)
print('标识', id(name))
print('类型', type(name))
print('值', name)
'''
v5le0n9
标识 1893355704496
类型 <class 'str'>
值 v5le0n9
'''

当变量被多次赋值后,变量名会指向新的空间,旧的那个如果没有其他变量指向它,则成为内存垃圾。

5. 数据类型

数据类型 python中表示 例子
整数类型 int 98
浮点数类型 float 2.66
布尔类型 bool True, False
字符串类型 str ‘v5le0n9’

5.1 整数类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
n1 = 90
n2 = -72
n3 = 0
print(n1, type(n1))
print(n2, type(n2))
print(n3, type(n3))
print('十进制', 118)
print('二进制转十进制', 0b1011010)
print('八进制转十进制', 0o1234567)
print('十六进制转十进制', 0x1a4b5d)
'''
90 <class 'int'>
-72 <class 'int'>
0 <class 'int'>
十进制 118
二进制转十进制 90
八进制转十进制 342391
十六进制转十进制 1723229
'''

5.2 浮点类型

1
2
3
4
5
6
7
8
9
a = 3.1415926
print(a, type(a))
n1 = 1.1
n2 = 2.2
print(n1 + n2)
'''
3.1415926 <class 'float'>
3.3000000000000003
'''
1
2
3
4
5
from decimal import Decimal
print(Decimal('1.1') + Decimal('2.2'))
'''
3.3
'''

5.3 布尔类型

1
2
3
4
5
6
print(True + 1)
print(False + 1)
'''
2
1
'''

5.4 字符串类型

1
2
3
4
5
6
7
8
9
10
str1 = 'v5le0n9'
str2 = "v5le0n9"
str3 = '''
v5le0n9
l30n9ry0n
'''
str4 = """
hhhhhhh
kkkkkkk
"""

5.5 数据类型转换

其他类型转字符串

1
2
3
4
5
6
7
8
9
10
11
name = "张三"
age = 23
print(type(name), type(age))
print('我叫' + name + ',今年' + str(age) + '岁')
age = 22.3
print(str(age))
'''
<class 'str'> <class 'int'>
我叫张三,今年23岁
22.3
'''

其他类型转整型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
s1 = '128'
f1 = 98.7
s2 = '76.77'
ff = True
s3 = 'Hello'
print(int(s1), type(int(s1)))
print(int(f1), type(int(f1)))
#print(int(s2), type(s2)) #小数串不能转化为整型
print(int(ff), type(int(ff)))
#print(int(s3), type(s3)) #不是整型数字串
'''
128 <class 'int'>
98 <class 'int'>
1 <class 'int'>
'''

其他类型转浮点型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
s1 = '128.77'
s2 = '76'
ff = True
s3 = 'Hello'
ii = 98
print(float(s1), type(float(s1)))
print(float(s2), type(float(s2)))
print(float(ff), type(float(ff)))
#print(float(s3), type(float(s3))) #不是数字串
print(float(ii), type(float(ii)))
'''
128.77 <class 'float'>
76.0 <class 'float'>
1.0 <class 'float'>
98.0 <class 'float'>
'''

其他类型转布尔类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
s1 = '128.77'
s2 = '76'
ff = True
s3 = 'Hello'
ii = 98
i2 = 0
print(bool(s1), type(bool(s1)))
print(bool(s2), type(bool(s2)))
print(bool(ff), type(bool(ff)))
print(bool(s3), type(bool(s3)))
print(bool(ii), type(bool(ii)))
print(bool(i2), type(bool(i2)))
'''
True <class 'bool'>
True <class 'bool'>
True <class 'bool'>
True <class 'bool'>
True <class 'bool'>
False <class 'bool'>
'''

6. input函数

用于用户输入。

1
2
3
4
5
6
7
present = input('你猜我在干嘛\n')
print(present, type(present))
'''
你猜我在干嘛
你猜我猜不猜
你猜我猜不猜 <class 'str'>
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#从终端输入两个整数,计算两个数的和
num1 = input("输入第一个:")
num2 = input("输入第二个:")
print(type(num1), type(num2))
print(num1 + num2)
'''
输入第一个:10
输入第二个:30
<class 'str'> <class 'str'>
1030
'''

num1 = int(input("输入第一个:"))
num2 = int(input("输入第二个:"))
print(type(num1), type(num2))
print(num1 + num2)
'''
输入第一个:10
输入第二个:30
<class 'int'> <class 'int'>
40
'''

7. 运算符

7.1 算术运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
print(1 + 1)
print(1 - 1)
print(1 * 1)
print(1 / 2) #除法
print(11 // 2) #整除
print(2**4) #幂运算
'''
2
0
1
0.5
5
16
'''
运算符 表示 例子 结果
% 取余(一正一负要公式,向下取整) 9%4 1
余数=被除数-除数*商 9%-4
9-(-4)*(-3)
-3
// 整除(一正一负向下取整) 11//2 5
9//-4 -3
-9//4 -3

7.2 赋值运算符

1
2
3
4
5
6
7
8
9
a = 3
a = b = c = 20
a, b, c = 10, 20, 30
a += 10
c //= a

a, b = 10, 20
a, b = b, a
print(a, b) #20 10

7.3 比较运算符

1
2
3
4
5
6
7
8
9
a, b = 10, 20
print(a > b)
print(a == b)
print(a != b)
'''
False
False
True
'''
1
2
3
4
5
6
7
8
9
10
11
a = 10
b = 10
print(a == b)
#比较对象的标识用is/isnot
print(a is b)
print(a is not b)
'''
True
True
False
'''
1
2
3
4
5
6
7
8
9
10
11
12
list1 = [11,22,33,44]
list2 = [11,22,33,44]
print(list1 == list2)
print(list1 is list2)
print(id(list1))
print(id(list2))
'''
True
False
2189001749064
2189001776136
'''

7.4 布尔运算符

运算符 运算数 运算结果 备注
and True True True 当两个运算都为True时,运算结果才为True
True False False
False True False
False False False
or True True True 只要有一个运算数为True,运算结果就为True
True False True
False True True
False False False
not True False 如果运算数为True,运算结果为False
False True 如果运算数为False,运算结果为True
1
2
3
4
5
6
7
8
9
10
11
w = 'Hello world'
print('v' in w)
print('h' in w)
print('w' in w)
print('a' not in w)
'''
False
False
True
True
'''

7.5 位运算

运算符 备注
& 对应数位都为1,结果数位才是1,否则为0
\ 对应数位都为0,结果数位才是0,否则为1
<< 高位溢出舍弃,低位补0
>> 低位溢出舍弃,高位补0

7.6 运算符的优先级

算术运算 > 位运算 > 比较运算 > 布尔运算 > 赋值运算

8. 程序的组织结构

流程控制:顺序结构、选择结构、循环结构

8.1 选择结构

8.1.1 单分支结构

1
2
if 条件表达式:
条件执行体
1
2
3
4
5
money = 10000
x = int(input("请输入取款金额:"))
if money >= x:
money -= x
print("取款成功,余额为:", money)

8.1.2 双分支结构

1
2
3
4
if 条件表达式:
条件执行体1
else:
条件执行体2
1
2
3
4
5
6
7
money = 10000
x = int(input("请输入取款金额:"))
if money >= x:
money -= x
print("取款成功,余额为:", money)
else:
print("取款失败,余额不足")

8.1.3 多分支结构

1
2
3
4
5
6
7
8
if 条件表达式:
条件执行体1
elif 条件表达式2:
条件执行体2
elif 条件表达式N:
条件执行体N
else:
条件执行体N+1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
grade = 50
if grade >= 90 and grade <= 100:
print('A')
elif grade >=80 and grade < 90:
print('B')
elif grade >= 70 and grade < 80:
print('C')
elif grade >=60 and grade < 70:
print('D')
elif grade < 60 and grade >= 0:
print('E')
else:
print("非法数据!")

#离谱写法
grade = 90
if 90<=grade<=100:
print('A')
elif 80<=grade<90:
print('B')
...

8.1.4 嵌套if语句

1
2
3
4
5
6
7
if 条件表达式:
if 内层条件表达式:
内存条件执行体1
else:
内层条件执行体2
else:
条件执行体

8.1.5 条件表达式

条件表达式是if…else的简写。

1
x if 判断条件 else y

运算规则:如果判断条件的布尔值为True,条件表达式的返回值为x,否则条件表达式的返回值为False。

1
2
3
4
num_a = int(input("请输入第一个整数:"))
num_b = int(input("请输入第二个整数:"))
print(num_a) if num_a >= num_b else print(num_b)
print(str(num_a) + '大于等于' + str(num_b) if num_a >= num_b else str(num_a) + '小于' + str(num_b))

8.2 pass语句

pass语句什么都不做,只是一个占位符,用在语法上需要语句的地方。

什么时候使用:先搭建语法结构,还没想好代码怎么写

哪些语句一起使用:

  • if语句的条件执行体
  • for-in语句的循环体
  • 定义函数时的循环体
1
2
3
4
5
answer = input('您是会员吗?y/n')
if ansewr == 'y':
pass
else:
pass

8.3 range函数

range函数用于生成一个整数序列,返回值是一个迭代器对象。

1
2
3
4
5
6
7
8
#创建一个(0, stop)之间的整数序列,步长为1
range(stop)

#创建一个(start, stop)之间的整数序列,步长为1
range(start, stop)

#创建一个(start, stop, step)之间的整数序列,步长为step
range(start, stop, step)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
r = range(10)
print(r)
print(list(r))

r = range(1, 10)
print(list(r))

r = range(1, 10, 2)
print(list(r))
print(10 in r)
'''
range(0, 10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 3, 5, 7, 9]
False
'''

8.4 循环结构

8.4.1 while循环

1
2
while 条件表达式:
条件执行体(循环体)
1
2
3
4
a = 1
while a < 10:
print(a)
a += 1
1
2
3
4
5
6
7
8
9
#计算1-100偶数和
a = 1
result = 0
while a <= 100:
#if a % 2 == 0:
if not a%2:
result += a
a += 1
print(result)

8.4.2 for-in循环

in表达从(字符串、序列等)中依次取值,又称为遍历。

1
2
for 自定义的变量 in 可迭代对象:
循环体

循环体内不需要访问自定义变量,可以将自定义变量替代为下划线。

1
2
3
4
5
6
7
8
for item in 'v5le0n9':
print(item)

for i in range(10):
print(i)

for _ in range(5):
print('hello')
1
2
3
4
5
6
#计算1-100偶数和
sum = 0
for i in range(1, 101):
if not i%2:
sum += i
print(sum)
1
2
3
4
5
6
7
8
9
10
11
12
13
#计算100-999的水仙花数:153=1**3+5**3+3**3
for i in range(100,1000):
ge = i % 10
shi = i // 10 % 10
bai = i // 100
if ge**3+bai**3+shi**3 == i:
print(i)
'''
153
370
371
407
'''

8.5 流程控制语句

8.5.1 break语句

用于结束循环结构,通常与分支结构if一起使用。

1
2
3
4
5
6
7
for i in range(3):
pwd = input("请输入密码:")
if pwd == '8888':
print('密码正确')
break
else:
print('密码不正确')
1
2
3
4
5
6
7
8
9
a = 0
while a < 3:
pwd = input("请输入密码:")
if pwd == '8888':
print('密码正确')
break
else:
print('密码不正确')
a += 1

8.5.2 continue语句

用于结束当前循环,进入下一次循环,通常与分支结构中的if一起使用。

1
2
3
4
5
#输出1-50之间所有5的倍数
for i in range(1,51):
if i%5 != 0:
continue
print(i)

8.6 else语句

1
2
3
4
5
6
#if条件表达式不成立时执行else
if...else

#没有碰到break时执行else
while...else
for...else
1
2
3
4
5
6
7
8
9
for i in range(3):
pwd = input("请输入密码:")
if pwd == '8888':
print('密码正确')
break
else:
print('密码不正确')
else:
print('密码已锁定')
1
2
3
4
5
6
7
8
9
10
11
a = 0
while a < 3:
pwd = input("请输入密码:")
if pwd == '8888':
print('密码正确')
break
else:
print('密码不正确')
a += 1
else:
print('密码已锁定')

8.7 嵌套循环

1
2
3
4
5
6
#打印九九乘法表
for i in range(1,10):
for j in range(1,i+1):
result = i * j
print(str(i) + '*' + str(j) + '=' + str(result), end='\t')#也可以写成end=' '
print('\n')#也可以写成print()

嵌套循环中的break和continue用于控制本层循环。

1
2
3
4
5
6
7
8
9
10
11
12
for _ in range(5):
for j in range(1, 11):
if j%2==0:
break
print(j)
'''
1
1
1
1
1
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
for _ in range(5):
for j in range(1, 11):
if j%2==0:
continue
print(j, end='\t')
print()
'''
1 3 5 7 9
1 3 5 7 9
1 3 5 7 9
1 3 5 7 9
1 3 5 7 9
'''

9. 列表

Python中的列表可以存储不同的数据类型。

1
2
3
4
5
6
7
8
9
lst = ['hello', 98, 44.2, True]
print(id(lst))
print(type(lst))
print(lst)
'''
1943553438088
<class 'list'>
['hello', 98, 44.2, True]
'''

9.1 创建列表

1
2
3
4
lst = ['hello', 98, True]
lst2 = list(['hello', 98, True])
lst3 = []
lst4 = list()

9.2 列表的特点

  1. 列表元素按顺序有序排序
  2. 索引映射唯一一个数据
  3. 列表可以存储重复数据
  4. 任意数据类型混存
  5. 根据需要动态分配和回收内存
1
2
3
4
5
6
7
lst = ['hello', 98, True, 98]
print(lst)
print(lst[0], lst[-4])
'''
['hello', 98, True, 98]
hello hello
'''

9.3 列表的查询

9.3.1 获取列表中指定元素的索引

列表中存在N个相同元素时,只返回相同元素中的第一个元素的索引。如果查询的元素在列表中不存在,则会抛出ValueError。还可以在指定的start和stop之间进行查找。

1
2
3
4
5
6
7
8
lst = ['hello', 98, True, 98]
print(lst.index(98))
#print(lst.index('hei')) #引发异常
print(lst.index(98,2,4))
'''
1
3
'''

9.3.2 获取列表中的单个元素

正向索引从0到N-1,逆向索引从-N到-1,指定索引不存在,则会抛出ValueError

1
2
3
4
5
6
7
lst = ['hello', 'world', 98, 'hello', 'world', 234]
print(lst[2])
print(lst[-3])
'''
98
hello
'''

9.3.3 获取列表中的多个元素

1
列表名[start: stop: step]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
lst = [10,20,30,40,50,60,70,80,90]
print('原列表', id(lst))
lst2 = lst[1:6:1]
print('切片列表', id(lst2))
print(lst2)
print(lst[:6:2])
print(lst[::-1])
print(lst[6:0:-2])
'''
原列表 1347062984904
切片列表 1347063015496
[20, 30, 40, 50, 60]
[10, 30, 50]
[90, 80, 70, 60, 50, 40, 30, 20, 10]
[70, 50, 30]
'''

9.3.4 列表元素的判断与遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
lst = [10,20,'python','world']
print(10 in lst)
print(20 not in lst)
for i in lst:
print(i)
'''
True
False
10
20
python
world
'''

9.4 列表元素的添加

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
32
33
lst = [10,20,30]
print('添加元素之前',lst,id(lst))
lst.append(100)
print('添加元素之后',lst,id(lst))

#将lst2作为一个元素添加到lst的末尾
lst2 = ['hello','v5le0n9']
lst.append(lst2)
print(lst)

#向列表的末尾一次性添加多个元素
lst.extend(lst2)
print(lst)

#在下标为1的位置上插入元素90
lst.insert(1,90)
print(lst)

#列表切片
lst3 = [True, False, 'hello']
lst[1:3] = lst3#将lst3的所有元素覆盖lst下标为1和2的元素
print(lst)
lst[:] = lst3
print(lst)
'''
添加元素之前 [10, 20, 30] 1236490777544
添加元素之后 [10, 20, 30, 100] 1236490777544
[10, 20, 30, 100, ['hello', 'v5le0n9']]
[10, 20, 30, 100, ['hello', 'v5le0n9'], 'hello', 'v5le0n9']
[10, 90, 20, 30, 100, ['hello', 'v5le0n9'], 'hello', 'v5le0n9']
[10, True, False, 'hello', 30, 100, ['hello', 'v5le0n9'], 'hello', 'v5le0n9']
[True, False, 'hello']
'''

9.5 列表元素的删除

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
32
33
34
35
36
lst = [10,20,30,40,50,60,30]
#移除列表重复元素的第一个元素
lst.remove(30)
print(lst)

#根据索引移除元素
lst.pop(1)
print(lst)
lst.pop()#默认将最后一个元素移除
print(lst)

#切片,删除至少一个元素,产生一个新的列表对象
new_lst = lst[1:3]
print('原列表',lst)
print('切片后产生的新列表', new_lst)

#不产生新的列表对象,删除原列表内容
lst[1:3] = []
print(lst)

#清除列表中的所有元素
lst.clear()
print(lst)

#将列表对象删除
del lst
#print(lst) #抛出异常
'''
[10, 20, 40, 50, 60, 30]
[10, 40, 50, 60, 30]
[10, 40, 50, 60]
原列表 [10, 40, 50, 60]
切片后产生的新列表 [40, 50]
[10, 60]
[]
'''

9.6 列表元素的修改

1
2
3
4
5
6
7
8
9
10
lst = [10,20,30,40]
lst[2] = 100
print(lst)

lst[1:3] = [300,400,500,600]
print(lst)
'''
[10, 20, 100, 40]
[10, 300, 400, 500, 600, 40]
'''

9.7 列表元素的排序

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
lst = [20,40,10,98,54]
print('排序前的列表', lst, id(lst))

#开始排序,调用列表对象的sort方法,升序排序
lst.sort()
print('排序后的列表', lst, id(lst))

lst.sort(reverse = True)
print(lst)

#使用内置函数sorted()对列表进行排序,将产生一个新的列表对象
lst = [20,40,10,98,54]
print(lst, id(lst))
new_lst = sorted(lst)
print(new_lst, id(new_lst))
desc_lst = sorted(lst, reverse = True)
print(desc_lst)
'''
排序前的列表 [20, 40, 10, 98, 54] 1692186177736
排序后的列表 [10, 20, 40, 54, 98] 1692186177736
[98, 54, 40, 20, 10]
[20, 40, 10, 98, 54] 1692186208264
[10, 20, 40, 54, 98] 1692186177736
[98, 54, 40, 20, 10]
'''

9.8 列表生成式

1
2
3
4
5
6
7
8
lst = [i for i in range(1,10)]
print(lst)
lst2 = [i*i for i in range(1,10)]
print(lst2)
'''
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
'''

10. 字典

以键值对的方式存储数据,是一个无序的序列。

字典的实现原理与查字典类似,查字典是先根据部首或拼音查找对应的页码,python中的字典是根据key查找value所在的位置。

10.1 字典的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
scores = {'张三':100, '李四':87, '王五':95}
print(scores)
print(type(scores))

student = dict(name='jack', age='20')
print(student)

d = {}
d2 = dict()
print(d,d2)
'''
{'张三': 100, '李四': 87, '王五': 95}
<class 'dict'>
{'name': 'jack', 'age': '20'}
{} {}
'''

10.2 字典元素的获取

1
2
3
4
5
6
7
8
9
10
11
12
13
scores = {'张三':100, '李四':87, '王五':95}
print(scores['张三'])
#print(scores['陈六']) #异常

print(scores.get('张三'))
print(scores.get('陈六'))
print(scores.get('麻七',99))#当麻七不存在在字典里,99为默认值
'''
100
100
None
99
'''

10.3 字典的增删改

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
#字典的判断
scores = {'张三':100, '李四':87, '王五':95}
print('张三' in scores)
print('张三' not in scores)

#字典元素的删除
del scores['张三']
print(scores)

scores.clear()
print(scores)

#字典元素的新增
scores['陈六'] = 98
print(scores)

#字典元素的修改
scores['陈六'] = 80
print(scores)
'''
True
False
{'李四': 87, '王五': 95}
{}
{'陈六': 98}
{'陈六': 80}
'''

10.4 获取字典视图

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
scores = {'张三':100, '李四':87, '王五':95}

#获取所有的key
keys = scores.keys()
print(keys)
print(type(keys))

#将所有的key组成的视图转换成列表
print(list(keys))

#获取所有的value
values = scores.values()
print(values)
print(type(values))
print(list(values))

#获取所有的键值对
items = scores.items()
print(items)
print(list(items)) #转换之后的列表元素由元组组成
'''
dict_keys(['张三', '李四', '王五'])
<class 'dict_keys'>
['张三', '李四', '王五']
dict_values([100, 87, 95])
<class 'dict_values'>
[100, 87, 95]
dict_items([('张三', 100), ('李四', 87), ('王五', 95)])
[('张三', 100), ('李四', 87), ('王五', 95)]
'''

10.5 字典元素的遍历

1
2
3
4
5
6
7
8
scores = {'张三':100, '李四':87, '王五':95}
for item in scores:
print(item, scores[item], scores.get(item))
'''
张三 100 100
李四 87 87
王五 95 95
'''

10.6 字典的特点

  • 字典中的所有元素都是一个键值对,key不允许重复,value可以重复

  • 字典中的元素是无序的

  • 字典中的key必须是不可变对象
  • 字典也可以根据需要动态地伸缩
  • 字典会浪费较大的内存,是一种使用空间换时间的数据结构

10.7 字典生成式

10.7.1 zip函数

用于将可迭代对象作为参数,将对象中对应的元素打包成一个元组,然后返回有这些元组组成的列表。

10.7.2 字典生成式

1
2
3
4
5
6
7
items = ['hei', 'biu', 'v5le0n9']
prices = [96, 98, 55, 66]
d = {item.upper():prices for item,prices in zip(items,prices)}
print(d)
'''
{'HEI': 96, 'BIU': 98, 'V5LE0N9': 55}
'''

11. 元组

元组是一个不可变序列。

不可变序列:字符串、元组,没有增删改操作。

可变序列:列表、字典,可以对序列执行增删改操作,对象地址不发生更改。

元组中存储的是对象的引用。

  • 如果元组中对象本身为不可变对象,则不能再引用其它对象
  • 如果元组中对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
t = (10,[20,30],9)
print(t)
print(type(t))
print(t[0],type(t[0]),id(t[0]))
print(t[1],type(t[1]),id(t[1]))
print(t[2],type(t[2]),id(t[2]))
print(id(100))
#t[1] = 100 #元组不允许修改元素

#由于[20,30]是列表,而列表是可变序列,所以可以向列中添加元素,而列表的内存地址不变
t[1].append(100)
print(t, id(t[1]))
'''
(10, [20, 30], 9)
<class 'tuple'>
10 <class 'int'> 140736278463024
[20, 30] <class 'list'> 2507573096776
9 <class 'int'> 140736278462992
140736278465904
(10, [20, 30, 100], 9) 2507573096776
'''

11.1 元组的创建方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
t = ('python', 'hello', 90)
print(t, type(t))
t2 = 'python', 'hello', 90
print(t2, type(t2))

#如果元组中只有一个元素,需要使用逗号和小括号
t3 = ('python',)
print(t3, type(t3))

t1 = tuple(('python', 'hello', 90))
print(t1)

t4 = ()
t5 = tuple()
print(t4, t5)
'''
('python', 'hello', 90) <class 'tuple'>
('python', 'hello', 90) <class 'tuple'>
('python',) <class 'tuple'>
('python', 'hello', 90)
() ()
'''

11.2 元组的遍历

1
2
3
4
5
6
7
8
9
10
t = ('python', 'hello', 90)
print(t[0])
for i in t:
print(i)
'''
python
python
hello
90
'''

12. 集合

集合与列表、字典一样都属于可变类型的序列,集合是没有的value的字典。

12.1 集合的创建

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
#集合中的元素不允许重复,集合中的元素是无序的
s = {2,3,4,5,5,6,7,7}
print(s)

s1 = set(range(6))
print(s1, type(s1))

#将列表转化为集合中
print(set([1,2,4,5,5,6,6]))

#将元组转化为集合
print(set((3,4,43,541)))

#将字符串转化为集合
print(set('python'))

#将集合转化为集合
print(set({124,2,3,5}))

#定义空集合
s2 = set()
print(s2)
'''
{2, 3, 4, 5, 6, 7}
{0, 1, 2, 3, 4, 5} <class 'set'>
{1, 2, 4, 5, 6}
{43, 3, 4, 541}
{'h', 'o', 'p', 't', 'n', 'y'}
{2, 3, 124, 5}
set()
'''

12.2 集合的增删改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#集合元素的判断
s = {10,20,30,405,50}
print(10 in s)
print(10 not in s)

#集合元素的新增操作
s.add(200) #一次添加一个元素
print(s)
s.update({200,300,400}) #一次至少添加一个元素
print(s)
s.update([75,60])
print(s)
s.update((78,22))
print(s)
'''
True
False
{200, 10, 50, 20, 405, 30}
{200, 10, 300, 400, 50, 20, 405, 30}
{200, 10, 75, 300, 400, 50, 20, 405, 60, 30}
{200, 10, 75, 300, 78, 400, 50, 20, 405, 22, 60, 30}
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#集合元素的删除
s = {10,20,30,405,50}
s.remove(30)
#s.remove(500) #抛出异常
print(s)

#不抛出异常
s.discard(500)
s.discard(10)
print(s)

#随机删除一个元素
s.pop()
#s.pop(50) #不能指定参数
print(s)

s.clear()
print(s)
'''
{10, 50, 20, 405}
{50, 20, 405}
{20, 405}
set()
'''

12.3 集合间的关系

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
32
33
34
35
36
#判断两个集合是否相等
s = {10,20,30,40}
s2 = {30,40,20,10}
print(s == s2)
print(s != s2)

#判断是否为子集
s1 = {10,20,30,40,50,60}
s2 = {10,20,30,40}
s3 = {10,20,90}
s4 = {10,20,90}
print(s2.issubset(s1))
print(s3.issubset(s1))
print(s4.issubset(s3))

#判断是否为父集
print(s1.issuperset(s2))
print(s1.issuperset(s3))
print(s4.issuperset(s3))

#是否没有交集
print(s2.isdisjoint(s3))
s4 = {100,200,300}
print(s4.isdisjoint(s3))
'''
True
False
True
False
True
True
False
True
False
True
'''

12.4 集合的数学操作

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
32
33
34
35
#交集
s1 = {10,20,30,40}
s2 = {20,30,40,50,60}
print(s1.intersection(s2))
print(s1 & s2) #intersection()与&等价,交集操作
print(s1, s2)

#并集
print(s1.union(s2))
print(s1 | s2)
print(s1, s2)

#差集
print(s1.difference(s2))
print(s1 - s2)
print(s1, s2)

#对称差集
print(s1.symmetric_difference(s2))
print(s1 ^ s2)
print(s1, s2)
'''
{40, 20, 30}
{40, 20, 30}
{40, 10, 20, 30} {40, 50, 20, 60, 30}
{40, 10, 50, 20, 60, 30}
{40, 10, 50, 20, 60, 30}
{40, 10, 20, 30} {40, 50, 20, 60, 30}
{10}
{10}
{40, 10, 20, 30} {40, 50, 20, 60, 30}
{50, 10, 60}
{50, 10, 60}
{40, 10, 20, 30} {40, 50, 20, 60, 30}
'''

12.5 集合生成式

用于生成集合的公式。

1
2
3
4
5
6
7
8
9
10
11
#列表生成式
lst = [i*i for i in range(10)]
print(lst)

#集合生成式
s = {i*i for i in range(10)}
print(s)
'''
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
'''

13. 列表、字典、元组、集合总结

数据结构 是否可变 是否重复 是否有序 定义符号
列表(list) 可变 可重复 有序 []
元组(tuple) 不可变 可重复 有序 ()
字典(dict) 可变 key不可重复,value可重复 无序 {key:value}
集合(set) 可变 不可重复 无序 {}

14. 字符串

14.1 字符串的创建与驻留机制

驻留机制的几种情况:

  • 字符串的长度为0或1时
  • 符合标识符的字符串
  • 字符串只在编译时进行驻留,而非运行时
  • [-5,256]之间的整数数字
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
a = 'v5le0n9'
b = "v5le0n9"
c = '''v5le0n9'''
print(a, id(a))
print(b, id(b))
print(c, id(c))

a = 'abc%'
b = 'abc%'
print(id(a), id(b))#在交互式窗口不同,在VS相同

a = '%'
b = '%'
print(id(a), id(b))

a = 'abc'
b = 'ab' + 'c'
c = ''.join(['ab','c'])
print(a, id(a), type(a))
print(b, id(b), type(b))
print(c, id(c), type(c))
'''
v5le0n9 1860778217520
v5le0n9 1860778217520
v5le0n9 1860778217520
1860778217968 1860778217968
1860707424368 1860707424368
abc 2658633804016 <class 'str'>
abc 2658633804016 <class 'str'>
abc 2658669390576 <class 'str'>
'''

14.2 字符串的常用操作

14.2.1 字符串的查询

功能 方法名称 作用
查询 index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1
1
2
3
4
5
6
7
8
9
10
11
s = 'hello,hello'
print(s.index('lo'))
print(s.rindex('lo'))
print(s.find('lo'))
print(s.rfind('lo'))
'''
3
9
3
9
'''

14.2.2 字符串大小写转换

1
2
3
4
5
6
7
8
9
10
s = 'hello python'
a = s.upper()
print(s,id(s))
print(a,id(a))
print(a.lower(),id(a.lower()))
'''
hello python 1765330538608
HELLO PYTHON 1765267539440
hello python 1765330535920
'''
1
2
3
4
5
6
7
8
9
s2 = 'hello V5LE0N9'
print(s2.swapcase())
print(s2.title())
print(s2.capitalize())
'''
HELLO v5le0n9
Hello V5Le0N9
Hello v5le0n9
'''

14.2.3 字符串的对齐

功能 方法名称 作用
字符串对齐 center() 居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数可选,默认空格,如果设置宽度小于实际宽度则返回原字符串
ljust() 左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数可选,默认空格,如果设置宽度小于实际宽度则返回原字符串
rjust() 右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数可选,默认空格,如果设置宽度小于实际宽度则返回原字符串
zfill() 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串长度,则返回字符串本身
1
2
3
4
5
6
7
8
9
10
11
s = 'hello v5le0n9'
print(s.center(20,'*'))
print(s.ljust(20,'*'))
print(s.rjust(20,'*'))
print(s.zfill(20))
'''
***hello v5le0n9****
hello v5le0n9*******
*******hello v5le0n9
0000000hello v5le0n9
'''

14.2.4 字符串的劈分

功能 方法名称 作用
字符串的劈分 split() 从字符串的左边开始劈分,默认的劈分字符是空格,返回值是一个列表。以通过参数sep指定劈分字符串是劈分符。通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分后,剩余的子串会单独作为一部分。
rsplit() 从字符串的右边开始劈分,默认的劈分字符是空格,返回值是一个列表。通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分后,剩余的子串会单独作为一部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
s = 'hello v5le0n9 hhhh'
lst = s.split()
print(lst)

sl = 'hello|v5le0n9|hhh'
print(sl.split(sep='|'))
print(sl.split(sep='|',maxsplit=1))

s = 'hello v5le0n9 hhhh'
lst = s.rsplit()
print(lst)
sl = 'hello|v5le0n9|hhh'
print(sl.rsplit(sep='|'))
print(sl.rsplit(sep='|',maxsplit=1))
'''
['hello', 'v5le0n9', 'hhhh']
['hello', 'v5le0n9', 'hhh']
['hello', 'v5le0n9|hhh']
['hello', 'v5le0n9', 'hhhh']
['hello', 'v5le0n9', 'hhh']
['hello|v5le0n9', 'hhh']
'''

14.2.5 字符串的判断

功能 方法名称 作用
判断字符串的方法 isidentifier() 判断指定的字符串是否为合法的标识符
isspace() 判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符等)
isalpha() 判断指定的字符串是否全部由字母组成
isdecimal() 判断指定的字符串是否全部由十进制数字组成
isnumeric() 判断指定的字符串是否全部由数字组成
isalnum() 判断指定的字符串是否全部由字母和数字组成
1
2
3
4
5
6
7
8
9
10
11
12
s = 'hello v5le0n9'
print(s.isidentifier()) #False
print('hello'.isidentifier()) #True
print('张三'.isidentifier()) #True
print('\t'.isspace()) #True
print('abc'.isalpha()) #True
print('张三'.isalpha()) #True
print('123'.isdecimal()) #True
print('123四'.isdecimal()) #False
print('123'.isnumeric()) #True
print('123四'.isnumeric()) #True
print('abc1'.isalnum()) #True

14.2.6 替换与合并

功能 方法名称 作用
字符串替换 replace() 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数
字符串的合并 join() 将列表或元组中的字符串合并成一个字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
s = 'hello v5le0n9'
print(s.replace('v5le0n9','Java'))
s1 = 'hello hei ha hu hu hu'
print(s1.replace('hu','hello',2))

lst = ['hello', 'java', 'python']
print('|'.join(lst))
print(' '.join(lst))

t = ('hello', 'java', 'python')
print(''.join(t))
print('*'.join('python'))
'''
hello Java
hello hei ha hello hello hu
hello|java|python
hello java python
hellojavapython
p*y*t*h*o*n
'''

14.3 字符串的比较

比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较。

比较原理:liang

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
print('apple' > 'app')	#True
print('apple' > 'banana') #False,相当于97 > 98
print(ord('a'),ord('b')) #97 98
print(ord('梁')) #26753

'''
== 比较的是value
is 比较的是id是否相等
'''
a = b = 'python'
c = 'python'
print(a == b)
print(a == c)
print(a is b)
print(a is c)
'''
True
True
True
True
'''

14.4 字符串的切片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
s = 'hello v5le0n9'
s1 = s[:5]
s2 = s[6:]
s3 = '!'
newstr = s1 + s3 +s2
print(s1)
print(s2)
print(newstr)
print(s[6:10:2])
print(s[::-1])
print(s[-7::1])
'''
hello
v5le0n9
hello!v5le0n9
vl
9n0el5v olleh
v5le0n9
'''

14.5 格式化字符串

1
2
3
4
5
6
7
8
9
10
name = '张三'
age = 20
print('我叫%s,今年%d岁' % (name, age))
print('我叫{0},今年{1}岁'.format(name, age))
print(f'我叫{name},今年{age}岁')
'''
我叫张三,今年20岁
我叫张三,今年20岁
我叫张三,今年20岁
'''
1
2
3
4
5
6
7
8
9
10
print('%10d' % 99)	#10表示宽度
print('hellohello')
print('%.3f' % 3.1415926) #.3表示小数点后3位
print('%10.3f' % 3.1415926)
'''
99
hellohello
3.142
3.142
'''
1
2
3
4
5
6
7
8
9
10
print('{0}'.format(3.1415926))
print('{0:.3}'.format(3.1415926)) #一共3位数
print('{0:.3f}'.format(3.1415926)) #3f表三位小数
print('{0:10.3}'.format(3.1415926)) #同时设置宽度和精度,一共10位,其中3位是小数
'''
3.1415926
3.14
3.142
3.14
'''

14.6 字符串的编码转换

编码:将字符串转换为二进制数据(bytes)

解码:将bytes类型的数据转换成字符串类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
s = "天涯共此时"

#编码
print(s.encode(encoding = 'GBK')) #GBK一个中文占两个字节
print(s.encode(encoding = 'UTF-8'))#UTF8一个中文占三个字节

#解码
byte = s.encode(encoding = 'GBK')
print(byte.decode(encoding = 'GBK'))
byte = s.encode(encoding = 'UTF-8')
print(byte.decode(encoding = 'UTF-8'))
'''
b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
天涯共此时
天涯共此时
'''

15. 函数

函数就是执行特定任务和完成特定功能的一段代码。

为什么需要函数?

  • 复用代码
  • 隐藏实现细节
  • 提高可维护性
  • 提高可读性便于调试

15.1 函数的创建与调用

1
2
3
4
5
6
7
8
def calc(a, b):
c = a + b
return c
result = calc(10, 20)
print(result)
'''
30
'''

15.2 函数的参数传递

1
2
3
4
5
6
def calc(a, b):	#a,b为形参
c = a + b
return c
result = calc(10, 20) #10,20为实参
print(result)
result = (calc(b=10, a=20)) #等号左侧为关键字参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def fun(arg1, arg2):
print('arg1 = ', arg1)
print('arg2 = ', arg2)
arg1 = 100
arg2.append(10)
print('arg1 = ', arg1)
print('arg2 = ', arg2)
n1 = 11
n2 = [22,33,44]
print(n1)
print(n2)
fun(n1,n2)
print(n1)
print(n2)
'''
11
[22, 33, 44]
arg1 = 11
arg2 = [22, 33, 44]
arg1 = 100
arg2 = [22, 33, 44, 10]
11
[22, 33, 44, 10]
'''

15.3 函数的返回值

如果函数没有返回值,return可以省略不写。

函数的返回值,如果是1个,直接返回类型。

函数的返回值,如果是多个,返回的结果为元组。

1
2
3
4
5
6
7
8
9
10
11
12
13
def fun(num):
odd = []
even = []
for i in num:
if i % 2:
odd.append(i)
else:
even.append(i)
return odd, even
print(fun([10,29,34,23,44,53,55]))
'''
([29, 23, 53, 55], [10, 34, 44])
'''

15.4 函数的参数定义

15.4.1 默认值参数

函数定义是,给形参设置默认值,只有与默认值不符的时候才需要传递实参。

1
2
3
4
5
def fun(a, b=10):
print(a, b)

fun(100) #只传一个参数,b采用默认值
fun(20,30) #30将默认值10替换

15.4.2 个数可变的位置参数

定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数。使用*定义个数可变的位置形参,结果为一个元组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def fun(*args):
print(args)
print(args[0])
fun(10)
fun(10,20)
fun(10,20,30)
'''
(10,)
10
(10, 20)
10
(10, 20, 30)
10
'''
1
2
3
def fun2(*args,*a):
pass
#以上代码程序报错,可变位置参数只能是一个

15.4.3 个数可变的关键字形参

定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参。使用**定义个数可变的关键字形参,结果为一个字典。

1
2
3
4
def fun(**args):
print(args)
fun(a = 10)
fun(a=10, b=20, c=30)
1
2
3
def fun2(**args,**a):
pass
#以上代码程序报错,可变关键字参数只能是一个
1
2
3
def fun3(*args1,**args2):
pass
#既有可变位置参数又有可变关键字参数,要求可变位置参数放在可变关键字参数之前

15.5 函数的参数总结

参数的类型 函数的定义 函数的调用 备注
位置实参
将序列中的每个元素都转换为位置实参 使用*
关键字实参
将字典中的每个键值对都转换为关键字实参 使用**
默认值形参
关键字形参 使用*
个数可变的位置形参 使用*
个数可变的关键字形参 使用**
1
2
3
4
5
6
7
8
9
10
def fun(a,b,c):	#形参
print('a = ', a)
print('b = ', b)
print('c = ', c)
fun(10,20,30) #位置实参
lst = [11,22,33]
fun(*lst) #将列表中的每个元素都转换为位置实参传入
fun(a=100, c=300, b=200) #关键字实参
dic = {'a':111, 'b':222, 'c':333}
fun(**dic) #在函数调用时,将字典中的键值对都转换为关键字实参传入
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
def fun(a, b=10):	#默认值形参
print('a = ', a)
print('b = ', b)

def fun2(*args): #个数可变的位置形参
print(args)

def fun3(**args2): #个数可变的关键字形参
print(args2)

fun2(10,20,30,40)
fun3(a=11,b=22,c=33)

def fun4(a,b,c,d):
print('a = ', a)
print('b = ', b)
print('c = ', c)
print('d = ', d)

fun4(10,20,30,40,50) #位置实参
fun4(a=10,b=20,c=30) #关键字实参
fun4(10,20,d=30,c=40)

#c,d只能采用关键字实参传递
def fun5(a,b,*,c,d): #从*之后,只能采用关键字参数传递
pass

16. 变量的作用域

变量的作用域:程序代码能访问该变量的区域。根据变量的有效范围可分为局部变量和全局变量。

局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量。

全局变量:函数体外定义的变量,可作用于函数内外。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def fun(a,b):
c = a + b
print(c)

name = 'v5le0n9' #全局变量
print(name)
def fun2():
print(name)
fun2()

def fun3():
global age #全局变量
age = 20
print(age)
fun3()
print(age)
'''
v5le0n9
v5le0n9
20
20
'''

17. 递归函数

在一个函数的函数体内调用该函数本身。

1
2
3
4
5
6
def fac(n):
if n==1:
return 1
else:
return n*fac(n-1)
print(fac(6))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#斐波那契数列
def fib(n):
if n==1:
return 1
elif n==2:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(6))

for i in range(1,7):
print(fib(i), end='\t')
'''
8
1 1 2 3 5 8
'''

18. Python的异常处理机制

18.1 try…except

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try:
a = int(input("请输入第一个整数:"))
b = int(input("请输入第二个整数:"))
result = a / b
print('结果为:', result)
except ZeroDivisionError:
print('对不起,除数不允许为0')
except ValueError:
print('只能输入数字串')
print('程序结束')
'''
请输入第一个整数:20
请输入第二个整数:0
对不起,除数不允许为0
程序结束
'''

18.2 try…except…else

如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try:
n1 = int(input("请输入一个整数:"))
n2 = int(input("请输入另一个整数:"))
result = n1 / n2
except BaseException as e:
print("出错了!")
print(e)
else:
print("结果为:", result)
'''
请输入一个整数:10
请输入另一个整数:0
出错了!
division by zero
'''

18.3 try…except…else…finally

finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try:
n1 = int(input("请输入一个整数:"))
n2 = int(input("请输入另一个整数:"))
result = n1 / n2
except BaseException as e:
print("出错了!")
print(e)
else:
print("结果为:", result)
finally:
print("总会被执行的代码")
print("程序结束")
'''
请输入一个整数:a
出错了!
invalid literal for int() with base 10: 'a'
总会被执行的代码
程序结束
'''

18.4 常见的异常类型

异常类型 描述
ZeroDivisionError 除零错误
IndexError 序列中没有此索引
KeyError 映射中没有这个键
NameError 未声明/初始化对象
SyntaxError Python语法错误
ValueError 传入无效参数

18.5 traceback模块

1
2
3
4
5
6
7
8
9
10
11
import traceback
try:
print(1 / 0)
except:
traceback.print_exc()
'''
Traceback (most recent call last):
File "E:\pythonproject\PythonApplication1\PythonApplication1\module2.py", line 3, in <module>
print(1 / 0)
ZeroDivisionError: division by zero
'''

19. 类与对象

19.1 类的创建

1
2
3
4
5
6
7
8
9
10
class Student:	#类名有一个或多个单词组成,每个单词首字母大写
pass
print(id(Student))
print(type(Student))
print(Student)
'''
2519221836392
<class 'type'>
<class '__main__.Student'>
'''
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
32
33
34
35
36
37
38
39
40
41
class Student:
native_pace = "广东" #属性

def __init__(self,name,age):
self.name = name
self.age = age

#实例方法
def eat(self):
print("学生在吃饭")

#静态方法
@staticmethod
def menthod(): #静态方法不允许写self符号
print("静态方法")

#类方法
@classmethod
def cm(cls):
print("类方法")

#在类之外定义的称为函数,在类内部定义的称为方法
def drink(): #函数
print("喝水")

#创建Student对象的实例对象
stu1 = Student('张三', 20)
print(id(stu1))
print(type(stu1))
print(stu1)
stu1.eat()
print(stu1.age)
Student.eat(stu1) #33行与31行代码相同
'''
2611936977032
<class '__main__.Student'>
<__main__.Student object at 0x0000026023936088>
学生在吃饭
20
学生在吃饭
'''

19.2 类属性、类方法、静态方法

类属性:类中方法外的变量称为类属性,被该类的所有对象共享

类方法:使用@classmethod 修饰的方法,使用类名直接访问的方法

静态方法:使用@staticmethod 修饰的方法,使用类名直接访问的方法

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
32
33
34
35
36
37
38
39
40
class Student:
native_pace = "广东" #属性

def __init__(self,name,age):
self.name = name
self.age = age

#实例方法
def eat(self):
print("学生在吃饭")

#静态方法
@staticmethod
def method(): #静态方法不允许写self符号
print("静态方法")

#类方法
@classmethod
def cm(cls):
print("类方法")

print(Student.native_pace)
stu1 = Student('张三',20)
stu2 = Student('李四',30)
print(stu1.native_pace)
print(stu2.native_pace)
Student.native_pace = "天津"
print(stu1.native_pace)
print(stu2.native_pace)
Student.cm()
Student.method()
'''
广东
广东
广东
天津
天津
类方法
静态方法
'''

19.3 动态绑定属性和方法

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
class Student:  
def __init__(self,name,age):
self.name = name
self.age = age

def eat(self):
print(self.name + "在吃饭")
stu1 = Student("张三", 20)
stu1.eat()
stu2 = Student("李四", 30)
stu2.eat()

#绑定属性
stu2.gender = '女'
print(stu2.name, stu2.age, stu2.gender)

#绑定方法
def show():
print("定义在类之外")
stu1.show = show
stu1.show()
'''
张三在吃饭
李四在吃饭
李四 30 女
定义在类之外
'''

19.4 封装

面向对象的三大特征:

  • 封装:提高程序的安全性
  • 继承:提高代码的复用性
  • 多态:提高程序的可扩展性和可维护性
1
2
3
4
5
6
7
8
class Car:
def __init__(self,brand):
self.brand = brand
def start(self):
print("汽车已启动...")
car = Car('宝马x5')
car.start()
print(car.brand)
1
2
3
4
5
6
7
8
9
10
11
12
13
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age #属性私有
def show(self):
print(self.name, self.__age)
stu = Student("张三", 20)
stu.show() #张三 20
print(stu.name) #张三
#print(stu.__age) #不能在类外部使用
print(dir(stu))
#['_Student__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'show']
print(stu._Student__age) #20,可以通过'_Student__age'访问

19.5 继承

如果一个类没有继承任何类,则默认继承object。python支持多继承,定义子类时,必须在其构造函数中调用父类的构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#定义父类
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))

#定义子类
class Student(Person):
def __init__(self, name, age, score):
super().__init__(name, age)
self.score = score
stu = Student('Jack', 20, '1001')
stu.info()
'''
姓名:Jack,年龄:20
'''
1
2
3
4
5
6
7
#多继承
class A(object):
pass
class B(object):
pass
class C(A,B):
pass

19.5.1 方法重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#定义父类
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))

#定义子类
class Student(Person):
def __init__(self, name, age, score):
super().__init__(name, age)
self.score = score
def info(self):
super().info()
print(self.score)
stu = Student('Jack', 20, '1001')
stu.info()
'''
姓名:Jack,年龄:20
1001
'''

19.5.2 object类

object类是所有类的父类,因此所有类都有object类的属性和方法。

内置函数dir()可以查看指定对象所有属性。

object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写。

1
2
3
4
5
6
7
8
9
class Student:
pass
stu = Student()
print(dir(stu))
print(stu)
'''
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
<__main__.Student object at 0x00000297B7A94788>
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name,self.age)
stu = Student('张三', 20)
print(dir(stu))
print(stu) #默认调用__str__()方法
print(type(stu))
'''
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
我的名字是张三,今年20岁
<class '__main__.Student'>
'''

19.6 多态

静态语言实现多态的三个必要条件,比如Java:

  1. 继承
  2. 方法重写
  3. 父类引用指向子类对象

动态语言(Python)的多态崇尚“鸭子类型”,当看到一只鸟走起来像鸭子、游起来像鸭子、叫起来像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。

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
class Animal(object):
def eat(self):
print("动物会吃")
class Dog(Animal):
def eat(self):
print("狗吃骨头")
class Cat(Animal):
def eat(self):
print("猫吃鱼")
class Person:
def eat(self):
print("人吃五谷杂粮")

def fun(obj):
obj.eat()
fun(Cat())
fun(Dog())
fun(Animal())
fun(Person())
'''
猫吃鱼
狗吃骨头
动物会吃
人吃五谷杂粮
'''

19.7 特殊的属性和方法

名称 描述
特殊属性 __dict__ 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法 __len\() 通过重写__len()__方法,让内置函数len()的参数可以是自定义类型
__add\() 通过重写__add__()方法,可使用自定义对象具有“+”功能
__new__() 用于创建对象
__init__() 对创建的对象进行初始化
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
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
class D(A):
pass

#创建C类的对象
x = C('Jack',20)
print(x.__dict__) #实例对象的属性字典
print(C.__dict__) #类对象的方法字典
print(x.__class__) #输出了对象所属的类
print(C.__bases__) #输出C类类型的元素
print(C.__base__) #输出第一个父类的元素
print(C.__mro__) #查看类的层次结构
print(A.__subclasses__()) #输出子类的列表
'''
{'name': 'Jack', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000002805E552AF8>, '__doc__': None}
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
<class '__main__.A'>
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>, <class '__main__.D'>]
'''
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
32
33
34
35
a = 20
b = 100
c = a + b
d = a.__add__(b)
print(c)
print(d)

class Student:
def __init__(self, name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)

stu1 = Student('v5le0n9')
stu2 = Student('李四')
s = stu1 + stu2
print(s)
s = stu1.__add__(stu2)
print(s)

lst = [22,33,44,11]
print(len(lst))
print(lst.__len__())
print(len(stu1))
'''
120
120
v5le0n9李四
v5le0n9李四
4
4
7
'''
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
class Person():
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj)))
return obj

def __init__(self,name,age):
print("__init__被调用执行了,self的id值为{0}".format(id(self)))
self.name = name
self.age = age

print("object类对象的id为:{0}".format(id(object)))
print("Person类对象的id为:{0}".format(id(Person)))

#创建Person类的实例对象
p1 = Person('张三', 20) #创建对象会执行__new__()和__init__(),将__init__()返回给p1
print('p1这个Person类的实例对象的id为:{0}'.format(id(p1)))
'''
object类对象的id为:140736155446064
Person类对象的id为:1253089495272
__new__被调用执行了,cls的id值为1253089495272
创建的对象的id为:1253119249672
__init__被调用执行了,self的id值为1253119249672
p1这个Person类的实例对象的id为:1253119249672
'''

19.8 类的浅拷贝与深拷贝

变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象。

浅拷贝:Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,原对象与拷贝对象会引用同一个子对象。

深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,原对象和拷贝对象所有的子对象也不相同。

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
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk

#变量的赋值
cpu1 = CPU()
cpu2 = cpu1
print(cpu1, id(cpu1))
print(cpu2, id(cpu2))

#类的浅拷贝
disk = Disk()
computer = Computer(cpu1, disk)
import copy
computer2 = copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
'''
<__main__.CPU object at 0x0000021A6ADE6348> 2312485364552
<__main__.CPU object at 0x0000021A6ADE6348> 2312485364552
<__main__.Computer object at 0x0000021A6ADE8148> <__main__.CPU object at 0x0000021A6ADE6348> <__main__.Disk object at 0x0000021A6ADE4EC8>
<__main__.Computer object at 0x0000021A6ADE8488> <__main__.CPU object at 0x0000021A6ADE6348> <__main__.Disk object at 0x0000021A6ADE4EC8>
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk

cpu1 = CPU()
disk = Disk()
computer = Computer(cpu1, disk)
#类的深拷贝
import copy
computer3 = copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer3,computer3.cpu,computer3.disk)
'''
<__main__.Computer object at 0x000001D8BF2B54C8> <__main__.CPU object at 0x000001D8BDAE2848> <__main__.Disk object at 0x000001D8BF2B4CC8>
<__main__.Computer object at 0x000001D8BF2B69C8> <__main__.CPU object at 0x000001D8BF2B6688> <__main__.Disk object at 0x000001D8BF2B6508>
'''

20. 模块

使用模块的好处:

  • 方便其他程序和脚本的导入并使用
  • 避免函数名和变量名冲突
  • 提高代码的可维护性
  • 提高代码的可重用性

20.1 模块的导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math
print(id(math))
print(type(math))
print(math)
print(math.pi)
print(dir(math))
print(math.pow(2,3))
print(math.ceil(9.001)) #向上取整
print(math.floor(9.999)) #向下取整
'''
1512215034680
<class 'module'>
<module 'math' (built-in)>
3.141592653589793
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
8.0
10
9
'''
1
2
3
4
5
from math import pi
print(pi)
'''
3.141592653589793
'''
1
2
3
4
5
#calc.py
def add(a, b):
return a + b
def div(a, b):
return a / b
1
2
3
import calc
print(calc.add(10,20))
print(calc.div(4, 2))

20.2 以主程序形式运行

在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定它们在哪个模块中运行。如果一个模块不是被导入到其它程序中执行,那么他可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__。

1
2
3
4
#calc2.py
def add(a, b):
return a + b
print(add(10,20))
1
2
3
4
5
6
import calc2
print(calc2.add(100,200))
'''
30
300
'''
1
2
3
4
5
6
#calc2.py
def add(a, b):
return a + b

if __name__ == '__main__':
print(add(10,20)) #只有当点击运行calc2.py时才运行
1
2
3
4
5
import calc2
print(calc2.add(100,200))
'''
300
'''

20.3 包

包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下。

作用:代码规范,避免模块名称冲突。

包与目录的区别:

  • 包含__init__.py文件的目录称为包
  • 目录里通常不包含__init__.py文件

包的导入:

1
import 包名.模块包

package1包中有module_A.py模块:

1
a = 10

module_B.py模块:

1
b = 100

在另一个模块中导入package1包。

1
2
3
import package1.module_A as ma	#as后面的是别名
print(package1.module_A.a)
print(ma.a)
1
2
from package1 import module_A	#导入模块
from package1.module_A import a #导入变量

20.4 常用的内置模块

模块名 描述
sys 与Python解释器及其环境操作相关的标准库
time 提供与时间相关的各种函数的标准库
os 提供了访问操作系统服务功能的标准库
calendar 提供与日期相关的各种函数的标准库
urllib 用于读取来自网上的数据标准库
json 用于使用JSON序列化和反序列化对象
re 用于在字符串中执行正则表达式匹配和替换
math 提供标准算数运算函数的标准库
decimal 用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging 提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能
1
2
3
4
5
6
7
8
9
10
11
import sys
print(sys.getsizeof(24))
print(sys.getsizeof(45))
print(sys.getsizeof(True))
print(sys.getsizeof(False))
'''
28
28
28
24
'''
1
2
3
4
5
6
7
import time
print(time.time())
print(time.localtime(time.time()))
'''
1647265802.3989463
time.struct_time(tm_year=2022, tm_mon=3, tm_mday=14, tm_hour=21, tm_min=50, tm_sec=2, tm_wday=0, tm_yday=73, tm_isdst=0)
'''
1
2
import urllib.request
print(urllib.request.urlopen('https://v5le0n9.github.io/').read())

21. 编码格式与文件读写

21.1 编码格式

Python的解释器使用的是Unicode(内存),.py文件在磁盘上使用UTF-8存储(外存)。

1
2
#默认为UTF-8编码
print("哈哈哈哈哈哈")

设置为GBK编码:

1
2
#encoding = gbk
print('哈哈哈哈哈哈')

21.2 文件读写原理

1
2
3
4
file = open('a.txt', 'r')
print(file.readlines())
file.close()
#每行的结果放在一个列表中

21.3 常用的文件打开模式

文件的类型:按文件中数据的组织形式,文件分为文本文件和二进制文件。

  • 文本文件:存储的是普通“字符”文本,默认为Unicode字符集,可以使用记事本程序打开。
  • 二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件打开。比如mp3音频文件,jpg图片,doc文档等。
打开模式 描述
r 以只读模式打开文件,文件的指针将会放在文件的开头
w 以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a 以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾
b 以二进制方式打开文件,不能单独使用,需要与其它模式一起使用,rb或wb
+ 以读写方式打开文件,不能单独使用,需与其它模式一起使用,a+
1
2
3
4
5
6
7
file = open('b.txt', 'w')
file.write('Python')
file.close()

file = open('b.txt', 'a')
file.write('Python')
file.close()
1
2
3
4
5
src_file = open('logo,png', 'rb')
target_file = open('copylogo.png', 'wb')
print(target_file.write(src_file.read()))
target_file.close()
src_file.close()

21.4 文件对象的常用方法

方法名 说明
read([size]) 从文件中读取size个字节或字符的内容返回,若省略[size],则读取到文件末尾,即一次读取文件所有内容
readline() 从文本文件中读取一行内容
readlines() 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str) 将字符串str内容写入文件
writelines(s_list) 将字符串列表s_list写入文本文件,不添加换行符
seek(offset [,whence]) 把文件指针移动到新的位置,offset表示相对于whence的位置:offset:为正往结束方向移动,为负往开始方向移动。
whence不同的值代表不同含义:
0:从文件头开始计算(默认值)
1:从当前位置开始计算
2:从文件尾开始计算
tell() 返回文件指针的当前位置
flush() 把缓冲区的内容写入文件,但不关闭文件
close() 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源
1
2
3
4
5
file = open('a.txt', 'r')
print(file.read(2))
print(file.readline())
print(file.readlines())
file.close()
1
2
3
4
5
file = open('c.txt', 'a')
file.write('hello')
lst = ['Java', 'Python']
file.writelines(lst)
file.close()
1
2
3
4
5
file = open('a.txt', 'r')
file.seek(2)
print(file.read())
print(file.tell())
file.close()
1
2
3
4
5
file = open('c.txt', 'a')
file.write('hello')
file.flush()
file.write('world')
file.close()

21.5 with语句

with语句可以自动管理上下文资源,不论什么么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的。

1
2
with open('a.txt', 'r') as file:
print(file.read())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'''
MyContentMgr实现了特殊方法:__enter__(),__exit__()称为该类对象遵守了上下文管理器协议
该类对象的实例对象,成为上下文管理器
'''
class MyContentMgr(object):
def __enter__(self):
print('enter方法被调用执行了')
return self
def __exit__(self,exc_type,exc_val,exc_tb):
print("exit方法被调用执行了")
def show(self):
print("show方法被调用执行了")
with MyContentMgr() as file:
file.show()
'''
enter方法被调用执行了
show方法被调用执行了
exit方法被调用执行了
'''
1
2
3
with open('logo.png', 'rb') as src_file:
with open('copy2logo.png', 'wb') as target_file:
target_file.write(src_file.read())

21.6 os模块的常用函数

os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。

os模块与os.path模块用于对目录或文件进行操作。

1
2
3
4
5
6
import os
os.system('notepad.exe')
os.system('calc.exe')

#直接调用可执行文件
os.startfile(r'D:\CTF\tools\IDA_Pro_v7.5\ida.exe')
函数 说明
getcwd() 返回当前的工作目录
listdir(path) 返回指定路径下的文件和目录信息
mkdir(path [,mode]) 创建目录
makedirs(path1/path2…[,mode]) 创建多级目录
rmdir(path) 删除目录
removedirs(path1/path2…) 删除多级目录
chdir(path) 将path设置为当前工作目录
1
2
3
4
5
6
7
8
9
10
import os
print(os.getcwd())
lst = os.listdir('../chap15')
print(lst)
os.mkdir('newdir2')
os.makedirs('A/B/C')
os.rmdir('newdir2')
os.removedirs('A/B/C')
os.chdir('E:\\vipp')
print(os.getcwd())

21.7 os.path模块操作目录相关函数

函数 说明
abspath(path) 用于获取文件或目录的绝对路径
exists(path) 用于判断文件或目录是否存在,如果存在返回True,否则返回False
join(path,name) 将目录与目录或者文件名拼接起来
splitext() 分离文件名和扩展名
basename(path) 从一个目录中提取文件名
dirname(path) 从一个路径中提取文件路径,不包括文件名
isdir(path) 用于判断是否为路径
1
2
3
4
5
6
7
8
9
import os.path
print(os.path.abspath('hello.py'))
print(os.path.exists('hello.py'), os.path.exists('v5le0n9.py'))
print(os.path.join('E:\\Python','demo13.py'))
print(os.path.split('E:\\Python\\demo13.py'))
print(os.path.splitext('demo13.py'))
print(os.path.basename('E:\\Python\\demo13.py'))
print(os.path.dirname('E:\\Python\\demo13.py'))
print(os.path.isdir('E:\\Python\\demo13.py'))
1
2
3
4
5
6
7
8
9
10
11
12
#列出指定目录下的所有py文件
import os
path = os.getcwd()
lst = os.listdir(path)
for filename in lst:
if filename.endswith('.py'):
print(filename)
'''
module1.py
module2.py
PythonApplication1.py
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os
path = os.getcwd()
lst_files = os.walk(path)
print(lst_files)
for dirpath,dirname,filename in lst_files:
'''
print(dirpath)
print(dirname)
print(filename)
'''
for dir in dirname:
print(os.path.join(dirpath,dir))
for file in filename:
print(os.path.join(dirpath,file))

22. CTF中常用字符转换

22.1 整数之间的进制转换

1
2
3
4
5
6
7
8
9
print(hex(11111))				# 0x2b67
print(int(hex(11111),16)) # 11111
print(oct(11111)) # 0o25547
print(int(oct(11111),8)) # 11111
print(hex(int(oct(11111),8))) # 0x2b67
# 进制之间不能跳过十进制互相转换
# print(bin(oct(11111),8))
print(bin(11111)) # 0b10101101100111
print(int(bin(11111),2)) # 11111

22.2 字符串转整数

1
2
3
4
print(int('23333'))				# 23333
print(int('23333',16)) # 144179
print(int('0x23333',16)) # 144179
print(int('23333',8)) # 9947

22.3 整数与字节串之间的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 字节串转整数
# 大端法
print(int.from_bytes(b'y\xcc\xa6\xbb',byteorder='big')) # 2043455163

# 小端法
print(int.from_bytes(b'y\xcc\xa6\xbb',byteorder='little')) # 3148270713

# 导入struct包
import struct
# 默认转化成元组形式,但只可以包含一个元素
print(struct.unpack('>L',b'y\xcc\xa6\xbb')) # (2043455163,)

# 取元组下标为0的元素
print(struct.unpack('>L',b'y\xcc\xa6\xbb')[0]) # 2043455163

# 整数转字节串
# 后面有几个整数就要写多少个格式化字符
print(struct.pack('>L',3148270713)) # b'\xbb\xa6\xccy'
print(struct.pack('<LLL',1,2,3)) # b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'

关于struct包pack和unpack的第一个参数:

22.4 字符串与字节串之间的转换

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
32
33
# 字符串转字节串
# 字符串编码为字节码
print('v5le0n9'.encode('ascii')) # b'v5le0n9'

# 如果有中文用utf-8编码
print('v5le0n9哈'.encode('utf-8')) # b'v5le0n9\xe5\x93\x88'

# 数字或字符数组编码成字节码
print(bytes(1)) # b'\x00'
# print(bytes(1,2,3)) # 当多个整型转换要先转化为数组
print(bytes([1,0xb,ord('3')])) # b'\x01\x0b3'

# 16进制字符串转字节串
print(bytes().fromhex('abcd45')) # b'\xab\xcdE'

# map(func,iterable)第一个参数表示函数,第二参数表示一个或多个序列
# 将后面序列都调用前面的函数,最后返回一个迭代器
# 将这个迭代器里的内容转化为字节串
print(bytes(map(ord,'\x01\x02\x31\x32\x97\x98'))) # b'\x01\x0212\x97\x98'

# 字节串转字符串
# 字节码解码为字符串
print(bytes(b'v5le0n9\xe5\x93\x88').decode('utf-8')) # v5le0n9哈

# 将里面的内容先转为字节串,再转化为字符串,截取下标为2到-1的字符串
print(str(bytes(b'\x01\x0212'))[2:-1]) # \x01\x0212

# 字节串转16进制,再转字符串,截取下标为2到-1的字符串
import binascii
print(str(binascii.b2a_hex(b'\x01\x0212'))[2:-1]) # 01023132

# 字节串转16进制,再以字符串的形式插入列表
print([hex(x) for x in bytes(b'\x01\x0212')]) # ['0x1', '0x2', '0x31', '0x32']