初识 Python

注释

  • 单行注释:# 注释内容
  • 多行注释:""" 注释内容 """

变量

格式:变量名 = 数据值

1
2
a = 10
print(a)

数据类型

Python中有6种常用的值类型:

数据类型 描述
数字(Number) 整数(int)、浮点数(float)、复数(complex)、布尔(bool)
字符串(String) 由一组任意字符组成
列表(List) 有序的可变序列
元组(Tuple) 有序的不可变序列
集合(Set) 无序的不重复集合
字典(Dictionary) 无序的Key-Value集合

查看数据类型

使用type()可以查看数据类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Number
print(type(10))
print(type(3.14))
print(type(3 + 4j))
print(type(True))

# String
print(type("abc"))

# List
print(type([1, 2, 3]))

# Tuple
print(type((1, 2, 3)))

# Set
print(type({1, 2, 3}))

# Dictionary
print(type({"张三": 18, "李四": 19}))

数据类型转换

使用数据类型()可以转换数据类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# int()
i = int(3.14)
print(i)
print(type(i))

# float()
f = float(10)
print(f)
print(type(f))

# str()
s = str(True)
print(s)
print(type(s))

标识符

Python中的标识符命名规则如下:

  • 只能是字母、数字、下划线_和中文(不推荐)
  • 不能以数字开头
  • 不能是关键字
  • 区分大小写

关键字

使用help("keywords")可以查看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

运算符

算术运算符

运算符 描述
+
-
*
/
// 整除
% 取余
** 指数
1
2
3
4
5
6
7
print(2 + 3)
print(2 - 3)
print(2 * 3)
print(2 / 3)
print(2 // 3)
print(2 % 3)
print(2 ** 3)

赋值运算符

运算符 描述
= 直接赋值
+= 加后赋值
-= 减后赋值
*= 乘后赋值
/= 除后赋值
//= 整除后赋值
%= 取余后赋值
**= 幂后赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
a = 10
print(a)

a += 2
print(a)

a -= 2
print(a)

a *= 2
print(a)

a /= 2
print(a)

a //= 2
print(a)

a %= 2
print(a)

a **= 2
print(a)

关系运算符

运算符 描述
== 等于
!= 不等于
> 大于
>= 大于等于
< 小于
<= 小于等于
1
2
3
4
5
6
print(10 == 20)
print(10 != 20)
print(10 > 20)
print(10 >= 20)
print(10 < 20)
print(10 <= 20)

逻辑运算符

运算符 描述
and 逻辑与
or 逻辑或
not 逻辑非
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# and
print(True and True)
print(True and False)
print(False and True)
print(False and False)

# or
print(True or True)
print(True or False)
print(False or True)
print(False or False)

# not
print(not False)
print(not True)

位运算符

运算符 描述
& 按位与
| 按位或
^ 按位异或
~ 按位取反
<< 左移
>> 右移
1
2
3
4
5
6
print(4 & 6)
print(4 | 6)
print(4 ^ 6)
print(~4)
print(4 << 2)
print(4 >> 2)

成员运算符

运算符 描述
in 在…中
not in 不在…中

身份运算符

运算符 描述
is
is not 不是

字符串

特点:

  • 长度任意(取决于内存)
  • 支持下标索引
  • 允许重复字符串存在
  • 同元组,只读的、不可更改的

定义字符串

  • 单引号定义法:'abc'
  • 双引号定义法:"abc"
  • 三引号定义法:"""abc"""
1
2
3
4
5
6
7
s1 = 'abc'
s2 = "abc"
s3 = """abc"""

print(s1)
print(s2)
print(s3)

字符串嵌套

  • 单引号定义法,可以内含双引号
  • 双引号定义法,可以内含单引号
  • 使用转义字符\,可以消除引号效用
1
2
3
4
5
print('"abc"')
print("'abc'")

print("\"abc\"")
print('\'abc\'')

字符串拼接

使用+运算符可以实现字符串拼接:

1
2
3
4
name = "张三"
age = 18

print("姓名:" + name + "\t年龄:" + str(age))

字符串格式化

  • 使用%占位符
  • 使用str.format()
  • 使用f"{占位}"
1
2
3
4
5
6
7
8
9
10
11
name = "张三"
age = 18

# 方式1
print("姓名:%s\t年龄:%d" % (name, age))

# 方式2
print("姓名:{0}\t年龄:{1}".format(name, age))

# 方式3
print(f"姓名:{name}\t年龄:{age}")

常用的占位符如下:

格式符号 描述
%s 将字符串放入占位处
%d 将整数放入占位处
%f 将浮点数放入占位处
1
2
3
print("%s" % "abcde")
print("%d" % 12345)
print("%10.3f" % (10 / 3)) # 10表示占位宽度,3表示精度

字符串方法

获取元素

格式:str[索引]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
str = "python"

# 正索引
print(str[0])
print(str[1])
print(str[2])
print(str[3])
print(str[4])
print(str[5])

# 负索引
print(str[-6])
print(str[-5])
print(str[-4])
print(str[-3])
print(str[-2])
print(str[-1])

查询元素

格式:str.index(元素)

1
2
3
4
5
str = "python"

# 返回某个特定元素的索引
index = str.index("th")
print(index)

统计元素

格式:str.count(元素)

1
2
3
4
5
str = "python"

# 统计元素个数
count = str.count("th")
print(count)

字符串替换

格式:str.replace(原字符串, 新字符串)

1
2
3
4
5
str = "python"

# 字符串替换,生成新的字符串
newStr = str.replace("py", "")
print(newStr)

字符串分割

格式:str.split(分隔符)

1
2
3
4
5
str = "Hi Python"

# 字符串分割,生成新的字符串列表
list = str.split(" ")
print(list)

字符串规整

格式:str.strip()

1
2
3
4
5
6
7
8
9
10
str = " 123Python321 "

# 去除字符串前后的空白字符,生成新的字符串
newStr1 = str.strip()
print(newStr1)

# 去除字符串前后的指定字符串,生成新的字符串
# "1"和"2"和"3"字符都去除
newStr2 = newStr1.strip("123")
print(newStr2)

字符串长度

格式:len(str)

1
2
3
4
5
str = "python"

# 字符串长度
len = len(str)
print(len)

字符串遍历

1
2
3
4
5
6
7
8
9
10
11
str = "python"

# while循环遍历
index = 0
while index < len(str):
print(str[index])
index += 1

# for循环遍历
for element in str:
print(element)

字符串切片

格式:str[起始索引:结束索引:步长]

1
2
3
4
5
6
7
8
9
str = "python"

# 正索引切片
s1 = str[0:5:2]
print(s1)

# 负索引切片
s2 = str[-6:-1:2]
print(s2)

输入与输出

  • 输入:input()
  • 输出:print()
1
2
3
str = input("请输入:")

print(str, type(str))

JSON数据

JSON数据本质就是字符串。要么就是一个字典;要么就是一个列表,列表中的每一个元素是字典

Python对象转为JSON

格式:json.dumps()json.dump()

1
2
3
4
5
6
7
8
9
10
11
12
import json

# 准备数据
data = [
{"姓名": "张三", "年龄": 18},
{"姓名": "李四", "年龄": 19},
{"姓名": "王五", "年龄": 20}
]

# 转为JSON字符串
json_data = json.dumps(data, ensure_ascii=False) # 防止中文转成ASCII码
print(json_data)
1
2
3
4
5
6
7
8
9
10
11
12
import json

# 准备数据
data = [
{"姓名": "张三", "年龄": 18},
{"姓名": "李四", "年龄": 19},
{"姓名": "王五", "年龄": 20}
]

# 转为JSON字符串并写入本地磁盘
with open("aa.txt", "w", encoding="UTF-8") as f:
json.dump(data, f, ensure_ascii=False)

JSON转为Python对象

格式:json.loads()json.load()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import json

# 准备数据
data = [
{"姓名": "张三", "年龄": 18},
{"姓名": "李四", "年龄": 19},
{"姓名": "王五", "年龄": 20}
]

# 转为JSON字符串
json_data = json.dumps(data, ensure_ascii=False)

# 转为Python对象
list_data = json.loads(json_data)
print(list_data)
1
2
3
4
5
6
import json

with open("aa.txt", "r", encoding="UTF-8") as f:
# 本地JSON字符串转为Python对象
list_data = json.load(f)
print(list_data)

流程控制

顺序结构

程序自顶向下依次执行

分支结构

if语句

格式:if 判断条件: 条件成立时的语句体

1
2
if True:
print("Hello, World!")

if_else语句

格式:if 判断条件: 条件成立时的语句体 else: 条件不成立时的语句体

1
2
3
4
5
6
7
number_str = input("请输入一个整数:")
number = int(number_str)

if number % 2 == 0:
print(f"{number}是偶数")
else:
print(f"{number}是奇数")

if_elif_else语句

格式:if 判断条件1: 条件1成立时的语句体 elif 判断条件2: 条件2成立时的语句体 ... else: 条件都不成立时的语句体

1
2
3
4
5
6
7
8
9
10
11
12
number1_str = input("请输入第一个整数:")
number2_str = input("请输入第二个整数:")

number1 = int(number1_str)
number2 = int(number2_str)

if number1 > number2:
print(f"{number1}大于{number2}")
elif number1 < number2:
print(f"{number1}小于{number2}")
else:
print(f"{number1}等于{number2}")

循环结构

while循环

格式:while 条件: 循环体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import random

# 范围[1, 100]
random_number = random.randint(1, 100)

while True:
number_str = input("请输入一个1-100的整数:")
number = int(number_str)

if number > random_number:
print("猜大了!")
continue
elif number < random_number:
print("猜小了!")
continue
else:
print("猜对了!")
break

for循环

格式:for 临时变量 in 序列: 循环体

1
2
3
4
5
# 范围[1, 10)
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j} * {i} = {i * j}", end="\t")
print()

函数

定义函数

格式:def 函数名(参数): 函数体 return 返回值

1
2
3
4
5
6
def say_hi():
print("Hi~")


if __name__ == '__main__':
say_hi()

函数参数

位置参数

位置参数与传递参数时的位置有关:

1
2
3
4
5
6
def say_hi(name):
print(f"Hi~{name}")


if __name__ == '__main__':
say_hi("Jerry")

关键字参数

关键字参数与传递参数时的位置无关,且参数必须是键值对:

1
2
3
4
5
6
def say_hi(name):
print(f"Hi~{name}")


if __name__ == '__main__':
say_hi(name="Jerry")

注意:位置参数和关键字参数混用时,位置参数须在前

缺省参数

也叫默认参数:

1
2
3
4
5
6
def say_hi(name="Xxx"):
print(f"Hi~{name}")


if __name__ == '__main__':
say_hi()

注意:位置参数和缺省参数混用时,位置参数须在前

不定长参数

也叫可变参数。有两种类型:位置不定长和关键字不定长:

1
2
3
4
5
6
7
8
9
10
11
# 位置不定长:参数个数不限
def add(*args): # args是一个元组
sum = 0
for arg in args:
sum += arg
return sum


if __name__ == '__main__':
sum = add(10, 20)
print(sum)
1
2
3
4
5
6
7
# 关键字不定长:参数个数不限且必须为键值对
def user(**kwargs): # kwargs是一个字典,kw是keyword的缩写
print(kwargs)


if __name__ == '__main__':
user(id=1, name="张三", age=18)

函数名作参数

即将一个函数作为参数,传递给另一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
def test(compute, a, b):
# print(type(compute))
result = compute(a, b)
print(result)


def compute(x, y):
return x + y


if __name__ == '__main__':
test(compute, 10, 20)

函数返回值

返回单个值

1
2
3
4
5
6
7
def add(a, b):
return a + b


if __name__ == '__main__':
sum = add(10, 20)
print(sum)

返回空类型

1
2
3
4
5
6
7
8
def say_hi():
print("Hi~")
return None # 此语句可省略

if __name__ == '__main__':
result = say_hi()

print(result, type(result))

返回多个值

1
2
3
4
5
6
7
8
9
def test():
return 1, 2


if __name__ == '__main__':
x, y = test()

print(x)
print(y)

函数说明文档

可以使用多行注释来实现函数的文档说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
def add(a, b):
"""
add函数可以接收两个参数,实现两个数相加的功能
:param a: 形参a表示相加的其中一个数字
:param b: 形参b表示相加的另一个数字
:return: 返回值表示两数相加的结果
"""
return a + b


if __name__ == '__main__':
sum = add(10, 20)
print(sum)

global关键字

可以使用global关键字来实现函数内对全局变量的更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 10


def update():
# global关键字声明一个全局变量
global a
a = 20


if __name__ == '__main__':
print(a)
update()
print(a)

lambda匿名函数

格式:lambda 参数: 函数体(一行代码)

  • def关键字,用于定义带有名称的函数,可以重复使用
  • lambda关键字,用于定义匿名函数,只能使用一次
1
2
3
4
5
6
7
def test(compute, a, b):
result = compute(a, b)
print(result)


if __name__ == '__main__':
test(lambda x, y: x + y, 10, 20)

列表

特点:

  • 可以容纳多个元素,上限为2**63 - 1
  • 可以容纳不同类型的元素
  • 元素是有序存储的
  • 允许重复元素存在
  • 列表是可更改的

定义列表

格式:[元素1, 元素2, ...]list()

1
2
3
4
5
6
7
# 方式1
list1 = [None, 123, "abc", True]
print(list1, type(list1))

# 方式2
list2 = list(list1)
print(list2, type(list2))

列表索引

列表的索引可以是正,也可以是负:

1
2
3
4
5
6
7
8
9
10
11
12
13
list = [None, 123, "abc", True]

# 正索引:最小为0
print(list[0])
print(list[1])
print(list[2])
print(list[3])

# 负索引:最大为-1
print(list[-4])
print(list[-3])
print(list[-2])
print(list[-1])

列表方法

查询元素

格式:list.index(元素)

1
2
3
4
5
list = [None, 123, "abc", True]

# 返回某个特定元素的索引
index = list.index("abc")
print(index)

更新元素

格式:list[索引] = 值

1
2
3
4
5
list = [None, 123, "abc", True]

# 更新某个列表元素
list[-1] = False
print(list)

插入元素

格式:list.insert(索引, 元素)

1
2
3
4
5
list = [None, 123, "abc", True]

# 在列表的特定位置插入元素
list.insert(2, ["p", "y", "t", "h", "o", "n"])
print(list)

追加元素

  • 方式1:list.append(元素)
  • 方式2:list.extend(数据容器)
1
2
3
4
5
6
7
8
9
list = [None, 123, "abc", True]

# 在列表末尾追加某个元素
list.append(3.14)
print(list)

# 在列表末尾追加一批元素
list.extend(list)
print(list)

删除元素

  • 方式1:del list[索引]
  • 方式2:list.pop(索引)
  • 方式3:list.remove(元素)
1
2
3
4
5
6
7
8
9
10
11
12
list = [None, 123, "abc", True]

# 删除指定索引的列表元素
del list[0]
print(list)

list.pop(-1)
print(list)

# 删除元素在列表中的第一个匹配项
list.remove("abc")
print(list)

统计元素

格式:list.count(元素)

1
2
3
4
5
list = [None, 123, "abc", True]

# 统计元素个数
count = list.count("abc")
print(count)

清空元素

格式:list.clear()

1
2
3
4
5
list = [None, 123, "abc", True]

# 清空元素
list.clear()
print(list)

列表长度

格式:len(list)

1
2
3
4
5
list = [None, 123, "abc", True]

# 列表长度
len = len(list)
print(len)

列表遍历

1
2
3
4
5
6
7
8
9
10
11
list = [None, 123, "abc", True]

# while循环遍历
index = 0
while index < len(list):
print(list[index])
index += 1

# for循环遍历
for element in list:
print(element)

列表切片

格式:list[起始索引:结束索引:步长]

1
2
3
4
5
6
7
8
9
list = [None, 123, "abc", True]

# 正索引切片
list1 = list[0:3:2]
print(list1)

# 负索引切片
list2 = list[-4:-1:2]
print(list2)

元组

特点:

  • 可以容纳多个元素
  • 可以容纳不同类型的元素
  • 元素是有序存储的
  • 允许重复元素存在
  • 元组是只读的、不可更改的
  • 只有一个元素时,需要加逗号

定义元组

格式:(元素1, 元素2, ...)tuple()

1
2
3
4
5
6
7
# 方式1
t1 = (None, 123, "abc", True)
print(t1, type(t1))

# 方式2
t2 = tuple(t1)
print(t2, type(t2))

元组索引

同列表,元组也有索引:

1
2
3
4
5
6
7
8
9
10
11
12
13
tuple = (None, 123, "abc", True)

# 正索引
print(tuple[0])
print(tuple[1])
print(tuple[2])
print(tuple[3])

# 负索引
print(tuple[-4])
print(tuple[-3])
print(tuple[-2])
print(tuple[-1])

元组方法

查找元素

格式:tuple.index(元素)

1
2
3
4
5
tuple = (None, 123, "abc", True)

# 返回某个特定元素的索引
index = tuple.index("abc")
print(index)

统计元素

格式:tuple.count(元素)

1
2
3
4
5
tuple = (None, 123, "abc", True)

# 统计元素个数
count = tuple.count("abc")
print(count)

元组长度

格式:len(tuple)

1
2
3
4
5
tuple = (None, 123, "abc", True)

# 元组长度
len = len(tuple)
print(len)

元组遍历

1
2
3
4
5
6
7
8
9
10
11
tuple = (None, 123, "abc", True)

# while循环遍历
index = 0
while index < len(tuple):
print(tuple[index])
index += 1

# for循环遍历
for element in tuple:
print(element)

元组切片

格式:tuple[起始索引, 结束索引, 步长]

1
2
3
4
5
6
7
8
9
tuple = (None, 123, "abc", True)

# 正索引切片
t1 = tuple[0:3:2]
print(t1)

# 负索引切片
t2 = tuple[-4:-1:2]
print(t2)

集合

特点:

  • 可以容纳多个元素
  • 可以容纳不同类型的元素
  • 元素是无序存储的
  • 不允许重复元素存在
  • 集合是可更改的

定义集合

格式:{元素1, 元素2, ...}set()

1
2
3
4
5
6
7
# 方式1
set1 = {None, 123, "abc", True, None, 123, "abc", True}
print(set1)

# 方式2
set2 = set(set1)
print(set2)

集合方法

添加元素

格式:set.add(元素)

1
2
3
4
5
set = {None, 123, "abc", True}

# 添加某个新元素
set.add(3.14)
print(set)

移除元素

格式:set.remove(元素)

1
2
3
4
5
set = {None, 123, "abc", True}

# 移除某个元素
set.remove(True)
print(set)

获取元素

格式:set.pop()

1
2
3
4
5
set = {None, 123, "abc", True}

# 随机获取某个元素
element = set.pop()
print(element)

清空元素

格式:set.clear()

1
2
3
4
5
set = {None, 123, "abc", True}

# 清空元素
set.clear()
print(set)

集合长度

格式:len(set)

1
2
3
4
5
set = {None, 123, "abc", True}

# 集合长度
len = len(set)
print(len)

差集

格式:set.difference(集合)

1
2
3
4
5
6
7
8
9
10
11
set1 = {1, 2, 3, 4, 5}
set2 = {3, 4, 5, 6, 7}

# 求两个集合的差集,返回新的集合(A - B)
set3 = set1.difference(set2)
print(set3)

# 消除集合1中与集合2相同的元素(A - A∩B)
set1.difference_update(set2)
print(set1)
print(set2)

交集

格式:set.intersection(集合)

1
2
3
4
5
6
7
8
9
10
11
set1 = {1, 2, 3, 4, 5}
set2 = {3, 4, 5, 6, 7}

# 求两个集合的交集,返回新的集合
set3 = set1.intersection(set2)
print(set3)

# 消除集合1中与集合2不同的元素(A - (A - B))
set1.intersection_update(set2)
print(set1)
print(set2)

并集

格式:set.union(集合)

1
2
3
4
5
6
set1 = {1, 2, 3, 4, 5}
set2 = {3, 4, 5, 6, 7}

# 求两个集合的并集,返回新的集合
set3 = set1.union(set2)
print(set3)

集合遍历

1
2
3
4
5
set = {None, 123, "abc", True}

# for循环遍历
for element in set:
print(element)

字典

特点:

  • 可以容纳多个元素
  • 可以容纳不同类型的元素
  • 每一个元素都是一个键值
  • Key不可重复(若重复,则覆盖)
  • 不支持下标索引
  • 字典是可更改的

定义字典

格式:{key1: value1, key2: value2, ...}dict()

1
2
3
4
5
6
7
# 方式1
dict1 = {"张三": 18, "李四": 19, "王五": 20}
print(dict1)

# 方式2
dict2 = dict(dict1)
print(dict2)

使用字典

格式:dict[key]

1
2
3
4
5
6
dict = {"张三": 18, "李四": 19, "王五": 20}

# 根据key获取value
print(dict["张三"])
print(dict["李四"])
print(dict["王五"])

字典方法

新增元素

格式:dict[key] = value

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 新增元素
dict["赵六"] = 21
print(dict)

更新元素

格式:dict[key] = value

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 更新元素
dict["李四"] = 25
print(dict)

删除元素

格式:dict.pop(key)

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 删除元素
dict.pop("王五")
print(dict)

清空元素

格式:dict.clear()

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 清空元素
dict.clear()
print(dict)

字典长度

格式:len(dict)

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 字典长度
len= len(dict)
print(len)

获取Key

格式:dict.keys()

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 获取key,返回元组
keys = dict.keys()
print(keys)

获取Value

格式:dict.values()

1
2
3
4
5
dict = {"张三": 18, "李四": 19, "王五": 20}

# 获取value,返回元组
values = dict.values()
print(values)

字典遍历

1
2
3
4
5
6
dict = {"张三": 18, "李四": 19, "王五": 20}

# for循环遍历
for key in dict:
value = dict[key]
print(f"姓名:{key}\t年龄:{value}")

文件操作

  • 打开文件
  • 读/写文件
  • 关闭文件

打开文件

格式:open(file, mode, encoding)

1
2
f = open("aa.txt", "r", encoding="UTF-8")
print(type(f))

常见的打开模式:

模式 描述
r 只读
w 只写
a 追加

读取文件

read(n)

1
2
3
4
5
6
7
f = open("aa.txt", "r", encoding="UTF-8")

# 读取指定字节长度的文本
text = f.read(1024)
print(text)

f.close()

readlines()

1
2
3
4
5
6
7
f = open("aa.txt", "r", encoding="UTF-8")

# 读取所有行,返回一个列表
lines = f.readlines()
print(lines)

f.close()

readline()

1
2
3
4
5
6
7
8
9
f = open("aa.txt", "r", encoding="UTF-8")

# 读取单行
for line in f:
# 去除换行符
line = line.strip("\n")
print(line)

f.close()

写出文件

格式:f.write()

1
2
3
4
5
6
7
8
9
f = open("aa.txt", "w", encoding="UTF-8")

# 写入内容
f.write("Hello, World!")

# 刷新缓冲区
f.flush()

f.close()

关闭文件

防止程序一直占用文件资源:

1
2
3
f = open("aa.txt", "r", encoding="UTF-8")

f.close()

with open()

可以自动关闭文件,防止遗忘:

1
2
3
with open("aa.txt", "r", encoding="UTF-8") as f:
for line in f:
print(line)

异常

异常捕获

格式:try: 可能发生错误的代码 except: 出现异常执行的代码

1
2
3
4
try:
f = open("aaa.txt", "r", encoding="UTF-8")
except:
print("出错了,文件不存在!")

捕获指定异常

格式:try: 可能发生错误的代码 except 异常名 as e: 出现异常执行的代码

1
2
3
4
try:
f = open("aaa.txt", "r", encoding="UTF-8")
except FileNotFoundError as e:
print(e)

捕获多个异常

格式:try: 可能发生错误的代码 except (异常1, 异常2) as e: 出现异常执行的代码

1
2
3
4
5
try:
# 1 / 0
f = open("aaa.txt", "r", encoding="UTF-8")
except (FileNotFoundError, ZeroDivisionError) as e:
print(e)

捕获所有异常

格式:try: 可能发生错误的代码 except Exception as e: 出现异常执行的代码

1
2
3
4
5
6
try:
# 1 / 0
# print(a)
f = open("aaa.txt", "r", encoding="UTF-8")
except Exception as e:
print(e)

try_except_else

1
2
3
4
5
6
7
8
9
try:
f = open("aa.txt", "r", encoding="UTF-8")
except Exception as e:
# 出现异常执行的代码
print(e)
else:
# 未出现异常执行的代码
lines = f.readlines()
print(lines)

try_except_else_finally

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f = None

try:
f = open("aa.txt", "r", encoding="UTF-8")
except Exception as e:
# 出现异常执行的代码
print(e)
else:
# 未出现异常执行的代码
lines = f.readlines()
print(lines)
finally:
if f:
# 无论是否出现异常,都要执行的代码
f.close()

异常传递

  • 异常出现时,如果未捕获,会向上传递,直到被捕获
  • 如果都未捕获,程序异常终止
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def func01():
print("func01开始")
1 / 0
print("func01结束")


def func02():
print("func02开始")
func01()
print("func02结束")


if __name__ == '__main__':
try:
func02()
except Exception as e:
print(e)

模块与包

  • 模块(Module),是一个Python文件,以.py结尾,里面包含类、变量、函数等

  • 包(package),就是一个文件夹,用来管理多个模块。由一堆模块和一个__init__.py文件组成

导入模块

格式:[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]

1
2
3
4
5
import time

print("程序开始执行")
time.sleep(5)
print("程序结束执行")

这等价于:

1
2
3
4
5
from time import sleep

print("程序开始执行")
sleep(5)
print("程序结束执行")
1
2
3
4
5
from time import *

print("程序开始执行")
sleep(5)
print("程序结束执行")

自定义模块

新建模块

1
2
3
# my_module.py
def add(a, b):
return a + b

导入模块

1
2
3
4
5
# main.py
from my_module import add

sum = add(10, 20)
print(sum)

__main__变量

1
2
3
4
5
6
7
8
9
# my_module.py
def add(a, b):
return a + b


# 测试代码(只在本模块有效)
if __name__ == '__main__':
sum = add(1, 2)
print(sum)
1
2
3
4
5
# main.py
from my_module import add

sum = add(10, 20)
print(sum)

__all__变量

当一个模块文件中有__all__变量时,使用from 模块名 import *就只能导入该列表中的元素

1
2
3
4
5
6
7
8
9
# my_module.py
__all__ = ["test_A"] # __all__限制import时能导入哪些内容

def test_A():
print("testA")


def test_B():
print("testB")
1
2
3
4
5
# main.py
from my_module import *

test_A()
# test_B()无法使用

自定义包

  • 新建包my_package
  • 新建模块my_module1my_module2
  • 配置__init__.py文件
1
2
# __init__.py
__all__ = ["my_module1"]
1
2
3
# my_module1.py
def test01():
print("test01")
1
2
3
# my_module2.py
def test02():
print("test02")
1
2
3
4
5
# main.py
from my_package import *

my_module1.test01()
# my_module2.test02()

安装第三方包

格式:pip install 包名

切换镜像源:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名

面向对象

成员变量

成员变量代表了对象的属性:

1
2
3
4
5
6
7
8
9
10
11
12
class Student:
name = None
age = None


if __name__ == '__main__':
stu = Student()

stu.name = "张三"
stu.age = 18

print(f"姓名:{stu.name}\t年龄:{stu.age}")

成员方法

成员方法代表了对象的行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student:
name = None
age = None

def say_hi(self):
# 访问成员变量,必须加self关键字
print(f"Hi~我叫{self.name}")


if __name__ == '__main__':
stu = Student()

stu.name = "张三"
stu.age = 18

stu.say_hi()

构造方法

格式:__init__(self)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student:
# name = None
# age = None

def __init__(self, name, age):
self.name = name
self.age = age
print("构造方法自动执行了")

def say_hi(self):
print(f"嗨,我是{self.name}")


if __name__ == '__main__':
stu = Student("张三", 18)
stu.say_hi()

魔术方法

__str__方法

直接打印对象会得到地址值,重写__str__内置方法可以打印对象的内部属性:

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 __str__(self):
return f"姓名:{self.name}\t年龄:{self.age}"


if __name__ == '__main__':
stu = Student("张三", 18)
print(stu)

__lt__方法

重写__lt__方法可以实现两个对象间的小于、大于比较:

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 __lt__(self, other):
return self.age < other.age


if __name__ == '__main__':
stu1 = Student("张三", 18)
stu2 = Student("李四", 19)

print(stu1 < stu2)

__le__方法

重写__le__方法可以实现两个对象间的小于等于、大于等于比较:

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

# 重载<=符号(less equal)
def __le__(self, other):
return self.age <= other.age


if __name__ == '__main__':
stu1 = Student("张三", 18)
stu2 = Student("李四", 19)

print(stu1 <= stu2)

__eq__方法

重写__eq__方法可以实现两个对象间的等于、不等于比较:

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

# 重载==符号(equal)
def __eq__(self, other):
return self.age == other.age


if __name__ == '__main__':
stu1 = Student("张三", 18)
stu2 = Student("李四", 19)

print(stu1 == stu2)

封装

  • 私有成员变量:以__开头的成员变量,仅类内可以访问
  • 私有成员方法:以__开头的成员方法,仅类内可以访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student:
def __init__(self, name, age):
self.name = name
# __age表明age是一个私有成员变量
self.__age = age

# __private_method表明是一个私有成员方法
def __private_method(self):
print("我是私有成员方法")


if __name__ == '__main__':
stu = Student("张三", 18)

print(stu.name)
# print(stu.__age)

# stu.__private_method()

继承

格式:class 子类(父类1, 父类2, ...):

  • 调用父类成员变量:super().成员变量
  • 调用父类成员方法:super().成员方法()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def __str__(self):
return f"姓名:{self.name}\t年龄:{self.age}"


class Student(Person):
def __init__(self, name, age):
# 调用父类构造方法
super().__init__(name, age)


if __name__ == '__main__':
stu = Student("张三", 18)
print(stu)

类型注解

变量类型注解

  • 方式1:变量: 类型
  • 方式2:# type: 类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 对基本变量进行注解
var_1: int = 10
var_2: float = 3.14
var_3: bool = True
var_4: str = "python"

# 对容器变量进行注解
lst: list[None, int, str, bool] = [None, 123, "abc", True]
dct: dict[str, int] = {"abc": 123}

# 对自定义对象进行注解
class Student:
pass


stu: Student = Student()
1
2
3
4
var_1 = 10          # type: int
var_2 = 3.14 # type : float
var_3 = True # type: bool
var_4 = "python" # type: str

函数形参类型注解

同变量类型注解方式1:

1
2
3
4
5
6
7
def add(x: int, y: int):
return x + y


if __name__ == '__main__':
sum = add(10, 20)
print(sum)

函数返回值类型注解

在函数名后加-> 类型来声明一个返回值类型注解:

1
2
3
4
5
6
7
def add(x: int, y: int) -> int:
return x + y


if __name__ == '__main__':
sum = add(10, 20)
print(sum)

Union类型注解

格式:Union[类型1, 类型2, ...]

1
2
3
4
5
6
7
8
from typing import Union

lst: list[Union[str, int]] = ["abc", 123]
dct: dict[str, Union[str, int]] = {"姓名": "张三", "年龄": 18}


def func(x: Union[str, int]) -> Union[str, int]:
pass

多态

同一个行为,使用不同的对象获得不同的行为:

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 Animal:
# 抽象方法(方法体为空实现,用pass代替)
def speak(self):
pass


class Dog(Animal):
def speak(self):
print("汪汪汪")


class Cat(Animal):
def speak(self):
print("喵喵喵")


def make_noise(animal: Animal):
animal.speak()


if __name__ == '__main__':
dog = Dog()
cat = Cat()

make_noise(dog)
make_noise(cat)

Python高阶

闭包

  • 定义双层嵌套函数,内层函数可以访问外层函数的变量

  • 将内层函数作为外层函数的返回值,此内层函数就是闭包函数

闭包优缺点

优点:

  • 无需定义全局变量即可实现通过函数持续地访问、修改某个值
  • 闭包使用的变量的作用域在函数内,难以被错误的调用修改

缺点:

  • 内部函数持续引用外部函数的值,这一部分内存空间无法被释放,一直被占用
1
2
3
4
5
6
7
8
9
10
def outer(logo):
def inner(msg):
print(f"<{logo}>{msg}</{logo}>")

return inner


if __name__ == '__main__':
fn = outer("html")
fn("Hello, World!")

nonlocal关键字

在闭包函数中需要修改外部函数的变量值,需要使用nonlocal关键字声明这个外部变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def outer(num1):
def inner(num2):
# 声明外部变量
nonlocal num1
num1 += num2
print(num1)

return inner


if __name__ == '__main__':
fn = outer(10)

fn(20)
fn(20)
fn(20)

装饰器

装饰器本质也是一种闭包,其功能主要在于不破坏目标函数原有代码和功能的前提下,为目标函数增加新功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time


def outer(func):
def inner():
print("我要睡觉了")
func()
print("我起床了")

return inner


def sleep():
print("睡眠中...")
time.sleep(5)


if __name__ == '__main__':
fn = outer(sleep)
fn()

其语法糖如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time


def outer(func):
def inner():
print("我要睡觉了")
func()
print("我起床了")

return inner


@outer
def sleep():
print("睡眠中...")
time.sleep(5)


if __name__ == '__main__':
sleep()

设计模式

设计模式是一种编程套路,可以极大地方便程序的开发

单例模式

作用:确保某个类只能有一个实例。一般用于某些工具类

1
2
3
4
5
# str_tools.py
class StrTools:
pass

str_tool = StrTools()
1
2
3
4
5
6
7
8
# main.py
from str_tools import str_tool

s1 = str_tool
s2 = str_tool

print(id(s1))
print(id(s2))

工厂模式

作用:需要大量创建一个类的实例

优点:

  • 大批量创建对象的时候,有统一的入口,易于代码维护
  • 当发生修改,仅修改工厂类的创建方法即可
  • 符合现实世界的模式,即由工厂来制作产品(对象)
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
class Person:
pass


class Worker(Person):
pass


class Student(Person):
pass


class Teacher(Person):
pass


class Factory:
def get_instance(self, p_type):
if p_type == "w":
return Worker()
elif p_type == "s":
return Student()
else:
return Teacher()


if __name__ == '__main__':
factory = Factory()

worker = factory.get_instance("w")
student = factory.get_instance("s")
teacher = factory.get_instance("t")

print(type(worker))
print(type(student))
print(type(teacher))

多线程

进程:一个运行中的程序,就是一个进程

线程:进程的实际工作最小单位

并行:不同的进程/线程在同一时间执行不同的任务

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
import threading
import time


def sing(s):
thread = threading.current_thread()
while True:
print(f"{thread.name}在唱{s}...")
time.sleep(3)


def dance(d):
thread = threading.current_thread()
while True:
print(f"{thread.name}在跳{d}...")
time.sleep(3)


if __name__ == '__main__':
t1 = threading.Thread(target=sing, args=("《丑八怪》", ), name="线程A")
t2 = threading.Thread(target=dance, kwargs={"d": "芭蕾舞"}, name="线程B")

t1.start()
t2.start()

网络编程

服务端开发

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
import socket

# 创建socket对象
socket_server = socket.socket()

# 绑定IP
socket_server.bind(("localhost", 8888))

# 监听端口
socket_server.listen(1) # 1表示仅允许与一个客户端通讯

# 等待客户端连接(返回一个元组)
conn, address = socket_server.accept()

print(f"客户端响应连接!IP信息为:{address}")

while True:
# 接收客户端信息
data = conn.recv(1024).decode("UTF-8") # 1024为缓冲区大小

print(f"接收到客户端发来的消息:{data}")

# 回复客户端消息
msg = input("请输入响应消息:")

if msg == "q":
break

conn.send(msg.encode("UTF-8"))

# 关闭连接
conn.close()
socket_server.close()

客户端开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import socket

# 创建socket对象
socket_client = socket.socket()

# 连接服务器
socket_client.connect(("localhost", 8888))

while True:
# 发送消息
msg = input("请输入发送消息:")

if msg == "q":
break

socket_client.send(msg.encode("UTF-8"))

# 接收服务器回复消息
data = socket_client.recv(1024).decode("UTF-8")

print(f"接收到服务端响应消息:{data}")

# 关闭连接
socket_client.close()