从零开始的Python学习之旅:笔记篇

开始的时候要注意了,新建的.py文件不能新建到venv文件夹里,因为这个是项目的虚拟环境文件。

入门篇笔记

打印-print函数

英文的括号,英文的引号,可以使用单引号或者双引号,里面放入要打印的文字。

1
2
3
4
print("")
print('')
print("hello word") # 示例
# 引号包括里面内的内容一整个被称为字符串"hello word"

字符串连接

可以把几个字符串用加号(+)连接成一个更长的再打印出来:

1
2
3
print("你好" + " 这是一句代码" + " 哈哈")

# 打印结果:你好这是一句代码哈哈

单双引号转义

如果内容本身就存在引号,就需要留意内容引号和外面包裹字符串的引号是单还是双

1
2
3
print("He said"good!"") # 错误示例
print('He said" good!"')# 应该把内外的引号区分开
print("He said' good!'")# 应该把内外的引号区分开

要是一段文字里刚好存在单引号和双引号,在字符串里的引号前面加一个反斜杠\,表明后面的引号是单纯的符号。

反斜杠\叫做转义符,加上之后python就知道把\和后面的内容一起读产生特殊的意思,在另一个笔记里有详细解释。

1
2
print("He said "Let's go!"")     # 错误示例
print("He said \"Let\'s go!\"") # 正确示例:在字符串里的引号前面加一个反斜杠 \

换行

因为python是读一行执行一行,所以不能回车换行。

1
2
3
print("第一行
第二行") # 错误示例
print("第一行\n第二行") # 正确示例\n为换行转义字符,打印出来后就会分行。在另外一个笔记内字符串中的转义字符中有详细讲解。

三引号跨行字符串

要是打印的内容非常的长,用\n换行转义字符就非常的麻烦,这里就要用到三引号,可以是三个连一起的单引号'''或者双引号""",用它包裹住文字python就会把新一行当作内容的换行,而不是代码语句的结束。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
print('''君不见黄河之水天上来,奔流到海不复回。
君不见高堂明镜悲白发,朝如青丝暮成雪。
人生得意须尽欢,莫使金樽空对月。
天生我材必有用,千金散尽还复来。
烹羊宰牛且为乐,会须一饮三百杯。
岑夫子,丹丘生,将进酒,杯莫停。
与君歌一曲,请君为我倾耳听。
钟鼓馔玉不足贵,但愿长醉不愿醒。
古来圣贤皆寂寞,惟有饮者留其名。
陈王昔时宴平乐,斗酒十千恣欢谑。
主人何为言少钱,径须沽取对君酌。
五花马、千金裘,呼儿将出换美酒,与尔同销万古愁。''')

变量

赋值操作my_name = ‘浅笑安然’ ,给变量一个值。赋值后可以通过变量名获取值反复使用。

python是从上到下执行的,赋值操作应该在使用点的前面,否则会报错。

1
my_name = '浅笑安然' #赋值

如果变量值变了,又不想失去原来的变量值,可以用变量给变量赋值。因为python是从上到下执行的,拆分来看还是很好理解的,我先对my_name赋值,然后my_ID= my_name的值,也就是my_ID = '浅笑安然',第三行对my_name重新赋值,my_name = '李',因为重上往下执行的所以完全不冲突。

1
2
3
4
5
my_name = '浅笑安然'  #对变量赋值
my_ID = my_name # 用变量给变量赋值
my_name = '李' #覆盖掉这个变量的原先值
print('当前my_name的值:' + 'my_name')#可以随时用print打印出当前的值了解情况。
print('当前my_ID的值:' + 'my_ID')#可以随时用print打印出当前的值了解情况。

python命名规则

变量应该易于理解和记忆,不能出现空格以及乱七八糟的符号。

  1. 尽量bu_yao_yong_pin_yin,容易认错,但是很适合我。
  2. python在3.0版本之后支持中文变量,如:用户名 ='1',不建议容易报错。
  3. 英文变量命名,下划线命名法,字母全部小写,不同单词用下划线分隔。如: user_age
  4. 变量名是大小写敏感的,大小写是不同的变量。
  5. 变量不要占用python的关键字如:print,如果对print进行赋值,后面就不能用print进行打印了。

Python数学运算

1
2
3
"6"  #被引号包裹的是字符串
6 #没小数点的是整数
6.0 #带小数点的是浮点数

python的加减乘除分别是:

  • 加 +
  • 减 -
  • 乘 *
  • 除 /
  • 乘方 ** (如:2的三次方2**3)

导入math函数库,这是一个专门提供数学运算函数的库。

导入方法:

1
2
3
4
5
6
7
8
9
import math # 在文件第一行输入,进入import库。
math.sin(1)#简单的应用,具体的可以去math库官方文档里查看。
print(math.sin(1))#要用print打印才可以看到计算的结果。
---------------------------------------------------------------
# 或者像下面这样,先对函数进行赋值,再打印结果。
print(math.sin(1))
sin = math.sin(1)
print(sin)

注释

  • # 我是一个注释
  • 如果是多行可以全部选中然后按下键盘的win + /,就可以一键注释。撤销注释再按一次就可以了。
  • '''注释内容'''包裹也可以进行多行注释。

数据类型

解释 数据类型
“hello”或 ‘hello’ 字符串 str
0,1,2,3… 整数 int
0.2,0.3… 浮点数 float
True False 布尔类型 bool
None 空值类型 NoneType

len(“”)函数

  • len("")函数可以计算字符串的长度。

索引

  • 字符串后面跟方括号,如: 'hello'[3]就能提取出相应位置的字符。
  • 可以把索引理解为顺序,不过索引是从0开始算的,所以如果要提取第四位字符,应该填入3

不确定某个对象类型的时候可以使用type(变量)函数,它会返回对象的类型,记得打印。

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 = "Hello world!"
print(len(s))

# 通过索引获取单个字符
print(s[0])#获取第一个字符
print(s[len(s) - 1])#获取最后一个数字,字符串长度减一。

# 布尔类型,首字母需要大写。
b1 = True
b2 = False

# 空值类型
n = None

# type函数
print(type(s))
print(type(b1))
print(type(n))
print(type(1.5))

# 不能对布尔类型的变量使用len函数,因此下面一行会报错
# len(b1)

交互模式

终端直接输入指令。打开命令提示符cmd,然后输入python3进入交互模式。

  • 好处: 不需要创建python就可以运行,不需要print就可以看到结果。
  • 坏处:所有输入的指令都不会保存。

输入input

  • input函数可以从用户那里获取信息,用法input(),里面放字符串作为提示信息。如:input('请输入身高:'),然后用户填写回车。
  • 但是这样并不知道用户输入了什么,要用变量去获取返回的值。如:user_height= input('请输入身高:')

int函数

input函数返回的数据是字符串,不能直接用作数学计算。

int函数可以把字符串 str类型转换成整数 int类型。

float函数

可以把其它数据类型转换成浮点数。

str函数

可以把其它数据类型转换成字符串 。

1
2
3
4
5
# BMI = 体重 / (身高 ** 2)
user_weight = float(input("请输入您的体重(单位:kg):"))# 字符串转换为浮点数,因为体重不可能是整数。
user_height = float(input("请输入您的身高(单位:m):"))# 字符串转换为浮点数,因为身高米不可能是整数。
user_BMI = user_weight / (user_height) ** 2
print("您的BMI值为:" + str(user_BMI)) # 字符串才可以打印出来

条件判断True False

在 Python 中,条件语句主要由 if 语句、else 语句和 elif 语句组成,用于根据不同的条件执行不同的代码块。

  • if 语句用于检查一个条件是否成立,如果成立,则执行 if 语句后面的代码块。
  • else 语句用于在 if 语句的条件不成立时执行代码块。
  • elif 语句用于在多个条件中检查下一个条件是否成立,如果成立,则执行 elif 语句后面的代码块。

条件类型

1
2
3
4
5
6
if [条件]:                  # 条件为真时
[执行语句] # 每行前面要有缩进
[执行语句]
else# 条件为假时
[执行语句]
[执行语句]

比较运算符

  • 等于号==
  • 不等号!=
  • 大于号>
  • 大于等于号>=
  • 小于号<
  • 小于等于号<=

案例

1
2
3
4
5
6
mood_index = int(input("对象今天的心情指数是:"))
if mood_index >= 60: #值大于等于60为真
print("恭喜,今晚应该可以打游戏,去吧皮卡丘!")
print("∠( ᐛ 」∠)_")
else: # mood_index < 60,值小于60为假
print("为了自个儿小命,还是别打了。")

嵌套条件语句

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
if [条件一]:                  # 满足条件一时,判断条件二
if [条件二]: # 满足条件二时,返回执行语句。
[执行语句] # 一次缩进约四个空格
[执行语句]
else
[执行语句]
[执行语句]
----------------------------------------------------------------------------
if [条件一]: # 满足条件一时,判断条件二 。不满足时,返回语句C。
if [条件二]: # 满足条件二时,返回执行语句,不满足时返回语句B。
[执行语句A] # 一次缩进约四个空格
else
[执行语句B]
else
[执行语句C]

----------------------------------------------------------------------------
if [条件一]:
[执行语句A]
elif [条件二]:
[执行语句B]
elif [条件三]:
[执行语句C]
else
[执行语句C]

案例

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
user_gender = input("请输入您的性别,M或F(M表示男,F表示女):")
# BMI = 体重 / (身高 ** 2)
user_weight = float(input("请输入您的体重(单位:kg):"))
user_height = float(input("请输入您的身高(单位:m):"))
user_BMI = user_weight / user_height ** 2
print("您的BMI值为:" + str(user_BMI))

# 偏瘦:user_BMI <= 18.5
# 正常:18.5 < user_BMI <= 25
# 偏胖:25 < user_BMI <= 30
# 肥胖:user_BMI > 30
if user_BMI <= 18.5:
if user_gender == "M":
print("先生您好,此BMI值属于偏瘦范围。")
elif user_gender == "F":
print("女士您好,此BMI值属于偏瘦范围。")
else:
print("此BMI值属于偏瘦范围。")
elif 18.5 < user_BMI <= 25:
if user_gender == "M":
print("先生您好,此BMI值属于正常范围。")
elif user_gender == "F":
print("女士您好,此BMI值属于正常范围。")
else:
print("此BMI值属于正常范围。")
elif 25 < user_BMI <= 30:
if user_gender == "M":
print("先生您好,此BMI值属于偏胖范围。")
elif user_gender == "F":
print("女士您好,此BMI值属于偏胖范围。")
else:
print("此BMI值属于偏胖范围。")
else:
if user_gender == "M":
print("先生您好,此BMI值属于肥胖范围。")
elif user_gender == "F":
print("女士您好,此BMI值属于肥胖范围。")
else:
print("此BMI值属于肥胖范围。")

逻辑运算

Python 中的 逻辑运算符 包括:与 and或 or非 not 三种

解释

(1)and

1
条件1 and 条件2
  • 并且
  • 两个条件同时满足,返回 True
  • 只要有一个不满足,就返回 `False``

(2) or

1
条件1 or 条件2
  • 或者
  • 两个条件只要有一个满足,返回 True
  • 两个条件都不满足,返回 False

(3) not

1
not 条件
  • 不是

运算优先级:not → and → or

可以通过括号等改变运算顺序,和加减乘除一样。

列表[]

一个空的列表用一个方括号[]表示。

  • gou_wu = ["键盘","鼠标"]这是一个列表。
  • append可以往列表里面加元素。
  • remove可以删除列表里的某个元素。
  • len(变量)函数可以获取列表元素的数量。
  • print(gou_wu[0])可以通过索引获取某个位置的元素。
  • max函数打印列表里的最大值
  • min函数打印列表里的最小值
  • print函数打印排序好的列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
gou_wu = ["键盘""鼠标"]   #列表示例

# 列表是可变的,往定义好的列表里加东西,可以用append。
gou_wu.append("耳机") #append表示往列表里加东西。
gou_wu.remove("键盘") #remove可以删除列表里的某个元素,前提是列表里已有的,否则报错。

print(gou_wu)# 可以随时打印列表检查元素

len(gou_wu)#函数可以获取列表元素的数量。

print(gou_wu[1]) = "音箱"#通过索引直接覆盖该位置原本的元素
----------------------------------------------------------------------------
#针对列表的内置函数:
print(max(num_list))# 打印列表里的最大值
print(min(num_list))# 打印列表里的最小值
print(sorted(num_list))# 打印排序好的列表

方法和函数的使用

  • 方法:对象.方法名(...),如gou_wu.append(“耳机”)。
  • 函数:函数名(对象),如len(gou_wu)。

案例

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
shopping_list = []
# 往购物清单里添加两个商品
shopping_list.append("键盘")
shopping_list.append("键帽")
# 往购物清单里移除一个商品
shopping_list.remove("键帽")
# 往购物清单里移除两个商品
shopping_list.append("音响")
shopping_list.append("电竞椅")
# 更改购物清单的第二个商品
shopping_list[1] = "硬盘"

# print(shopping_list)
# print(len(shopping_list))
# print(shopping_list[0])

# 定义一个价格列表
price = [799, 1024, 200, 800]
# 获取最高的价格
max_price = max(price)
# 获取最低的价格
min_price = min(price)
# 获取从低到高排序好的价格列表
sorted_price = sorted(price)
print(max_price)
print(min_price)
print(sorted_price)

字典{}

字典用于储存键key : 值value 对。键会有对应的值,键是用来查找值的。

  • 空的字典用{}表示
  • 键和值之间用:表示对应
  • 键值对直接用逗号分,
  • 获取某个键的值,在字典名后面跟[]里面放入键
  • 键的类型必须是不可变的
  • 字典是可变的
  • 增加新的键值对contacts["李四"]
  • 删除一个键值对del contacts["李四"]
  • 判断键是否存在"李四" in contacts
  • 查看有多少键值对len函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
contacts = {}#这是一个空的字典。
contacts = {"小明":"17500000000 ",
"小花":"17500000000 "}#这是一个字典。
contacts["小明"]#获取对应键的值
----------------------------------------------------------------------------
# 元组作为键
contacts = {("张三", 31):"17500000000 ",
("张三", 21):"13500000000 ",
("张三", 51):"13700000000 "}
contacts[("张三", 51)]#使用元组作为键
----------------------------------------------------------------------------
#增加新的键值对
contacts["李四"] = "1330000000"# 新增值是这样的,更新也是这样,原理是直接覆盖。

#删除一个键值对,要是本身就不存在则报错。
del contacts["李四"]

# 判断键是否存在
"李四" in contacts #会返回一个布尔值,判断该键是否存在于字典里。

len(contacts)#查看有多少键值对

元组

  • 元组用()表示
  • 元组是不可变的

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 结合input、字典、if判断,做一个查询流行语含义的电子词典程序
slang_dict = {"觉醒年代":"《觉醒年代》首次以电视剧的形式回溯中国共产党的孕育和创立过程,生动再现中国近代历史的大变局,深刻讲述中国人民是怎样选择了中国共产党。该剧播出后广受好评,成为党史学习教育的生动教材。",
"YYDS":"“永远的神”的拼音缩写,用于表达对某人的高度敬佩和崇拜。2021年东京奥运会期间,不管是杨倩夺得首金,还是全红婵一场决赛跳出三个满分,或是“苏神”站上百米决赛跑道,全网齐喊“YYDS”,奥运期间一度刷屏。"}
slang_dict["双减"] = "指进一步减轻义务教育阶段学生作业负担和校外培训负担。其目标是使学校教育教学质量和服务水平进一步提升,作业布置更加科学合理,学校课后服务基本满足学生需要,学生学习更好回归校园,校外培训机构培训行为全面规范。"
slang_dict["破防"] = "原指在游戏中突破了对方的防御,使对方失去防御能力。现指因遇到一些事或看到一些信息后情感上受到很大冲击,内心深处被触动,心理防线被突破。"
slang_dict["元宇宙"] = "源于小说《雪崩》的科幻概念,现指在XR(扩展现实)、数字孪生、区块链和AI(人工智能)等技术推动下形成的虚实相融的互联网应用和社会生活形态。现阶段,元宇宙仍是一个不断演变、不断发展的概念。Facebook(脸书)对外公布更名为“Meta”,该词即来源于“Metaverse”(元宇宙)。"
slang_dict["绝绝子"] = "该词流行于某网络节目,节目中一些粉丝用“绝绝子”为选手加油。多用于赞美,表示“太绝了、太好了”。这个词引发了网友对网络语言的关注和讨论。"
slang_dict["躺平"] = "该词指人在面对压力时,内心再无波澜,主动放弃,不做任何反抗。“躺平”更像是年轻人的一种解压和调整方式,是改变不了环境便改变心态的自我解脱。短暂“躺平”是为了积聚能量,更好地重新出发。"
slang_dict["伤害性不高,侮辱性极强"] = "一段网络视频中,两名男子相互夹菜,而同桌的另一名女子则显得很孤单。于是有网友调侃“伤害性不高,侮辱性极强”。后被网友用来调侃某事虽然没有实质性危害,但是却令人很难堪。"
slang_dict["我看不懂,但我大受震撼"] = "源自导演李安在纪录片《打扰伯格曼》(2013)里评价一部影视作品的话。现多用于表示自己对某件事情的不解、震惊。"
slang_dict["强国有我"] = "源自建党百年天安门广场庆典上青年学子的庄严宣誓。“请党放心,强国有我”是青年一代对党和人民许下的庄重誓言,彰显着新时代中国青年的志气、骨气、底气。"

query = input("请输入您想要查询的流行语:")
if query in slang_dict:
print("您查询的" + query + "含义如下")
print(slang_dict[query])
else:
print("您查询的流行语暂未收录。")
print("当前本词典收录词条数为:" + str(len(slang_dict)) + "条。")

for循环

这段听懵了,不太懂。以后着重复习。

  • for 变量名in 可迭代对象:
  • 字典名.keys()返回所有键
  • 字典名.values()返回所有值
  • 字典名.items()返回所有键值对

range

range(0,0)表示整数数列,第一个数字表示起始值,第二个表示结束值。结束值不在序列的范围内。

range(0,0,0)第一个数字表示起始值,第二个表示结束值,第三个数字表示步长。不指定的时候默认步长为1。

while循环

while后面跟上一个条件,求值出来为布尔值,都可以作为条件。判断为真执行下面的行动B,然后再次判断条件是否为真。为真继续执行行动B,直到为假结束。

1
2
while 条件A:
行动B

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
print("哈喽呀!我是一个求平均值的程序。")
total = 0
count = 0
user_input = input("请输入数字(完成所有数字输入后,请输入q终止程序):")
while user_input != "q":
num = float(user_input)
total += num
count += 1
user_input = input("请输入数字(完成所有数字输入后,请输入q终止程序):")
if count == 0:
result = 0
else:
result = total / count
print("您输入的数字平均值为" + str(result))

格式化字符串

format方法

在需要插入的地方用{}或者{数字}或者{变量}代替,花括号表示被替换的位置,数字0代表format的第一个参数,1代表第二个,以此类推。结尾使用format方法。.format(第一个参数,第二个参数)

下面是两种使用案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 示例:
year = "虎"
name = "老李"
message_content = ("""
律回春渐,新元肇启。
新岁甫至,福气东来。
金女{0}贺岁,欢乐祥瑞。
金{0}敲门,五福临门。
给{1}及家人拜年啦!
新春快乐,{0}年大吉!""".format(year,name))
print(message_content)
----------------------------------------------------------------------------
## 使用方法二:
year = "虎"
name = "老李"
message_content = ("""
律回春渐,新元肇启。
新岁甫至,福气东来。
金女{year}贺岁,欢乐祥瑞。
金{year}敲门,五福临门。
给{name}及家人拜年啦!
新春快乐,{year}年大吉!""".format(year=year, name=name)) #等号前面的是关键字,对应花括号内的关键字。等号后面的是参数值。
print(message_content)

f-字符串

在字符串前加前缀f,花括号里的内容会被直接求值,添加到字符串内。

1
2
3
4
5
6
7
8
9
10
year = "虎"
name = "老李"
message_content = f"""
律回春渐,新元肇启。
新岁甫至,福气东来。
金女{year}贺岁,欢乐祥瑞。
{year}敲门,五福临门。
{name}及家人拜年啦!
新春快乐,{year}年大吉!"""
print(message_content)

案例

{1:.2f} 是一种格式化字符串的方式,通常用于格式化浮点数。这个格式具有以下含义:

  • {} 中的数字 1 表示要在字符串中插入的变量的索引。在这个情况下,它表示插入的是第二个变量(索引从0开始计数)。
  • : 用于指示接下来的格式说明符。
  • .2f 是格式说明符的一部分,它表示要格式化的值是浮点数(f),并且保留两位小数点。
1
2
3
4
5
6
7
8
9
#format方法
gpa_dict = {"小明": 3.251, "小花": 3.251, "小李": 3.251, "小张": 3.251}
for name, gpa in gpa_dict.items():
print("{0}你好,你的当前绩点为:{1:.2f}".format(name, gpa))#{1}里面的:.2f是保留两位小数,这是一种格式化字符串的方式。
----------------------------------------------------------------------------
#方法
gpa_dict = {"小明": 3.251, "小花": 3.251, "小李": 3.251, "小张": 3.251}
for name, gpa in gpa_dict.items():
print(f"{name}你好,你的当前绩点为:{gpa:.2f}")#:.2f的意思同上

函数

DRY原则

DRY原则又称为Don’t repeat yourself(不要重复你自己),DRY的原则是──系统中的每一部分,都必须有一个单一的、明确的、权威的代表──指的是(由人编写而非机器生成的)代码和测试所构成的系统,必须能够表达所应表达的内容,但是不能含有任何重复代码。当DRY原则被成功应用时,一个系统中任何单个元素的修改都不需要与其逻辑无关的其他元素发生改变。此外,与之逻辑上相关的其他元素的变化均为可预见的、均匀的,并如此保持同步。

定义函数def

def关键词表示开始定义函数,后面跟上函数的名字、括号、冒号。比如:def sector():

  • 在括号里面给参数,就不需要赋值了,在调用函数的时候里面的参数会像变量,被赋值为传入值。
  • 函数里定义的变量只是局部变量,只作用于函数里面,到函数外就获取不到了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 扇形面积(A)= (θ/360) × π × r²
def sector_1():
# 接下来是一些定义函数的代码。
angle_1 = 160
radius_1 = 30
area = angle_1 / 360 * 3.14 * radius_1 ** 2
print(f"此扇形面积为:{area}")
sector_1()
----------------------------------------------------------------------------
# 优化_通过参数让函数变得通用
def sector(angle, radius):
area = angle / 360 * 3.14 * radius ** 2
print(f"此扇形面积为:{area}")
sector(160, 30)# 定义函数括号里的参数
sector(60, 15)

return语句

return语句用于从函数中返回一个值给调用者。当函数执行到return语句时,函数的执行就会立即停止,并将return后面的表达式的值作为函数的返回值。

1
2
3
4
5
6
7
8
def sector(angle, radius):
area = angle / 360 * 3.14 * radius ** 2
print(f"此扇形面积为:{area}")
return area # return用于从函数中返回一个值给调用者

# 调用扇形函数,参数分别为扇形的角度和半径
area_1 = sector(160, 30)
area_2 = sector(60, 15)

示例

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
"""
写一个计算BMI的函数,函数名为 calculate_BMI。
1. 可以计算任意体重和身高的BMI值
2. 执行过程中打印一句话,"您的BMI分类为:xx"
3. 返回计算出的BMI值

BMI = 体重 / (身高 ** 2)

BMI分类
偏瘦:BMI <= 18.5
正常:18.5 < BMI <= 25
偏胖:25 < BMI <= 30
肥胖:BMI > 30
"""

def calculate_BMI(weight, height):
BMI = weight / height ** 2
if BMI <= 18.5:
category = "偏瘦"
elif BMI <= 25:
category = "正常"
elif BMI <= 30:
category = "偏胖"
else:
category = "肥胖"
print(f"您的BMI分类为:{category}")
return BMI

result = calculate_BMI(1.8, 70)
print(result)

引入模块

  • import语句。在import后面跟上函数的名字。要用的时候用模块名.函数名模块名.变量名
  • from...import...语句,from后面跟上模块的名字,import后面跟上在模块里要使用的函数或变量
  • from...import*语句。from后面跟上模块的名字,import后面跟上*这样会把模块里面所有的内容引入。(不推荐用 * 的时候,模块里所有函数或变量都引入。如果引入了其它函数名字有重复就会冲突。)
1
2
3
4
5
6
7
8
9
10
11
12
# import语句
import statistics
print(statistics.median([19, -5, 36]))
print(statistics.mean([19, -5, 36]))
# from...import...语句
from statistics import median, mean
print(median([19, -5, 36]))
print(mean([19, -5, 36]))
# from...import*
from statistics import *
print(median([19, -5, 36]))
print(mean([19, -5, 36]))

引入官方库

Python 标准库 文档

  • 引入方法同上

引入第三方库

PyPI

  • 引入之前要进行安装pip install 库的名字
  • 引入方法同上

面向对象编程

面向对象编程和面向过程编程:

  • 过程:负责完成某个具体任务的代码。把要实现的事拆分成一个个步骤依次完成。

  • 对象:世界上有很多人和事物,每一个都可以看做一个对象,而每个对象都有自己的属性和行为,对象与对象之间通过方法来交互。

面向对象编程:

类是创建对象的模板,对象是类的实例。

特性:封装、继承、多态

  • 封装(Encapsulation):封装是将数据和操作数据的方法捆绑在一起,从而隐藏实现细节,使外部无法直接访问和修改数据。封装有助于保护数据的完整性,降低程序的复杂度,提高代码的可读性和可维护性。通过封装,我们可以将现实世界中的复杂问题简化为更易处理的模块。
  • 继承(Inheritance):继承是指子类可以继承父类的属性和方法,从而实现代码的重用。子类可以根据自己的需求对继承的属性和方法进行扩展或修改。继承有助于提高代码的复用性,降低程序的复杂度。通过继承,我们可以将现实世界中的相似问题抽象成共同的解决方案,从而简化问题的处理过程。
  • 多态(Polymorphism):多态是指同一种方法在不同的对象上具有不同的行为。多态可以分为参数多态和成员多态。参数多态是指同一个方法可以接受不同类型的参数,成员多态是指同一个方法在子类中可以有不同的实现。多态有助于提高程序的灵活性和可扩展性,使得程序能够适应不同的需求和场景。

属性和方法

  1. 属性(Attributes):属性是对象的特征或数据,它们描述了对象的状态。属性通常是对象的变量,用于存储数据。在类定义中,属性被定义为类的变量,并且在创建对象时,每个对象都有自己的属性。例如,在前面提到的 ATM 类中,编号银行支行 就是对象的属性。
  2. 方法(Methods):方法是与对象相关联的函数,它们用于定义对象的行为或功能。方法可以访问对象的属性,并且可以在方法内部对这些属性进行操作。在类定义中,方法被定义为类的函数。例如,在 ATM 类中,可以定义一个方法来模拟取款操作,这个方法可以使用对象的属性(如银行和支行信息)来执行取款操作。

关系:

  • 方法通常用于操作对象的属性。它们可以读取属性的值,修改属性的值,或者执行与属性相关的操作。
  • 方法定义了对象的行为,属性则定义了对象的状态。对象的状态和行为共同决定了对象的特性和功能。
  • 当你创建一个对象时,对象包含了属性和可以操作这些属性的方法。方法可以使用对象的属性,从而改变对象的状态或执行某些操作。

更加通俗易懂的说法:

属性:颜色、大小、体积

方法:移动、放大、变色、打印

创建类

类和对象之间的关系是:类是创建对象的模板,对象是类的实例。

1
2
3
4
5
6
7
8
9
10
# 先考虑各个对象有什么性质、能做什么,下面以ATM为例。
class ATM: # 创建一个名为ATM类
def __init__(self, 编号, 银行, 支行): # 提取ATM的性质(编号,银行,支行),定义ATM类。
self.编号 = 编号
#如果写成编号 = 编号,python会认为是普通的赋值,不会认为是对象的属性。
self.银行 = 银行#将传递给 ATM 类构造函数的 银行 参数的值保存到 ATM 对象内部,以便以后可以在对象中使用。
self.支行 = 支行
# 通过类创建ATM对象
atm1 = ATM("001","招商银行","南支行")# 创建对象是通过 类名(参数) ,这样__init__方法被调用,并返回一个对象。
atm2 = ATM("002","中国银行","北支行")

定义对象属性

创建类的语法:class 类的名字:属性是对象的特征或数据,它们描述了对象的状态。

def __init__(self):可以定义实例对象的属性,init用来初始化对象,self可以把属性的值绑定在实例对象上。

创建对象的语法:类名(参数),这样__init__方法会被调用,并返回一个对象。

  • 通过class关键字可以创建一个类。

    1
    2
    class ATM:  # 创建一个名为ATM类
    # 下面是定义类的代码
  • 定义类名用Pascla命名法,首字母大写,没有下划线。

  • 通过__init__这个构造函数,可以定义实例对象属性。

  • 通过class名字加括号( CuteCat("jojo",2,"白色"))可以调用__init__来创建新对象,并且赋值。

  • 获取对象的属性,用对象.属性名来获取。

    1
    print(cat1.name)#会返回cat1对象绑定的name属性的值。
1
2
3
4
5
6
class CuteCat:
# 下面是定义类的代码
def __init__(self): #括号里可以放任意数量的参数,第一个永远是self代表对象自身,它能把属性的值绑定在实例对象
self.name = "猫猫"# 说明是对象的name属性的值,可以把self看作对象来理解,就是 对象的名字=猫猫 ,如果不加self就不是给对象赋值而是普通的赋值操作
cat1 = CuteCat()# 创建一个 CuteCat 类的实例对象,并调用构造方法
print(cat1.name)

从参数获取值:将对象的属性加入参数里def __init__(self,属性1,属性2,属性3): ,然后__init__会执行,属性1被绑定为属性1参数的值.

创建对象时可以把值传入到属性:

1
2
3
4
5
6
7
class 类名:     #创建一个类
def __init__(self,猫猫名字,猫猫颜色,猫猫性别): # 将对象的属性加入参数里
self.猫猫名字 = 猫猫名字
cat1 = CuteCat("大橘",白色,"母")# 创建一个 Cat 类的实例对象,并传递属性值
print(f"猫猫的名字是:{cat1.猫猫名字}")
print(f"猫猫的颜色是:{cat1.猫猫颜色}")
print(f"猫猫的性别是:{cat1.猫猫性别}")

完整示例:

1
2
3
4
5
6
7
8
class CuteCat:
# 定义一个名为 CuteCat 的类
def __init__(self,cat_name,cat_age,cat_color): # 定义类的构造方法,当创建类的实例对象时,这个方法会自动被调用
self.name = cat_name
self.age = cat_age
self.color = cat_color
cat1 = CuteCat("jojo",2,"白色")# 创建一个 CuteCat 类的实例对象,并调用构造方法,同时传递了三个参数,分别是 cat_name,cat_age,cat_color
print(f"小猫{cat1.name}的年龄是{cat1.age}岁,花色是{cat1.color}")

定义对象方法

  • 方法表示对象能做什么事情,比如ATM能存钱,能取钱,能查询余额。

  • 定义的方法要写在class,也就是类里面,前面要有缩进,代表这是属于该类的方法。

  • 定义方法:def 方法名(self): self用来表示对象自身

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
# 先考虑各个对象有什么性质、能做什么,下面以ATM为例。
class ATM: # 创建一个名为ATM类
def __init__(self, 编号, 银行, 支行): # 提取ATM的性质(编号,银行,支行),定义ATM类。
self.编号 = 编号
self.银行 = 银行#将传递给 ATM 类构造函数的 银行 参数的值保存到 ATM 对象内部,以便以后可以在对象中使用。
self.支行 = 支行
self.余额 = 0 # ATM的初始余额为0
"""def 方法名(self, 参数1, 参数2, ...):
方法的代码实现
可以访问self来操作对象的属性和方法
方法的具体逻辑"""
def 存款(self, 金额):
# 存款方法,用于将指定金额添加到ATM的余额中
self.余额 += 金额
return f"{金额} 元已成功存入ATM,当前余额为 {self.余额} 元。"

def 取款(self, 金额):
# 取款方法,用于从ATM的余额中取出指定金额
if 金额 <= self.余额:
self.余额 -= 金额
return f"{金额} 元已成功取出,当前余额为 {self.余额} 元。"
else:
return "余额不足,无法取款。"

def 查询余额(self):
# 查询余额方法,用于查看ATM的当前余额
return f"当前余额为 {self.余额} 元。"
# 通过类创建ATM对象
atm1 = ATM("001","招商银行","南支行")
atm2 = ATM("002","中国银行","北支行")
# 定义ATN类的方法(方法:放在类里面的函数。属性:类里面的变量。)

# 使用ATM对象的方法进行操作
print(atm1.存款(1000))
print(atm1.查询余额())
print(atm1.取款(500))
print(atm1.查询余额())
  • 方法是与对象相关联的函数,它们用于定义对象的行为或功能。

  • 调用方法:对象.方法名()括号里面放入参数进行调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CuteCat:
# 下面是定义类的代码
def __init__(self, cat_name, cat_age, cat_color):
self.name = cat_name
self.age = cat_age
self.color = cat_color

def speak(self):
print("喵" * self.age)#"喵"✖年龄,如果一岁就打印一个,两岁打印两个。

def think(self, content):#创建think方法
print(f"小猫{self.name} 在思考{content}...")


cat1 = CuteCat("jojo", 2, "白色")
cat1.think("选择去抓沙发还是去撕纸箱")# 调用think方法给content参数
print(f"小猫{cat1.name}的年龄是{cat1.age}岁,花色是{cat1.color}")

示例

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
# 定义一个学生类
# 要求:
# 1. 属性包括学生姓名、学号,以及语数英三科的成绩
# 2. 能够设置学生某科目的成绩
# 3. 能够打印出该学生的所有科目成绩

class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
self.grades = {"语文": 0, "数学": 0, "英语": 0}

def set_grade(self, course, grade):
if course in self.grades:
self.grades[course] = grade

def print_grades(self):
print(f"学生{self.name} (学号:{self.student_id}) 的成绩为:")
for course in self.grades:
print(f"{course}: {self.grades[course]}分")

chen = Student("小陈", "100618")
chen.set_grade("语文", 92)
chen.set_grade("数学", 94)
chen.print_grades()
# zeng = Student("小曾", "100622")
# print(chen.name)
# zeng.set_grade("数学", 95)
# print(zeng.grades)

类继承

  • 给两个类共同的属性新建一个类,然后两个类都可以继承这个类。

  • 写法:在类名之后加上括号,填入父类的名字。class 银行(ATM):简单的来说就是银行包含了ATM的功能,这里把原来定义的ATM类作为银行类的一部分。

  • 调用时优先看所属的类有没有该方法,没有就往上找父类的同名方法用

  • super方法:super()会返回当前类的父类

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
class 哺乳类:  # 这是父类
def __init__(self,名字,性别):
self.名字 = 名字
self.性别 = 性别
self.眼睛数量 = 2

def 呼吸(self):
print(self.名字 + "在呼吸...")

def 拉屎(self):
print(self.名字 + "在拉屎...")


class 人类(哺乳类): # 这是子类
def __init__(self,名字,性别):
super().__init__(名字,性别)#super会返回当前类的父类,调用父类的构造函数
self.尾巴 = False #因为用了super就可以在子类里面接着父类的后面定义类
def 阅读(self):
print(self.名字 + "在阅读...")


class (哺乳类): # 这是子类
def __init__(self, 名字, 性别):
super().__init__(名字,性别)#super会返回当前类的父类
self.尾巴 = True
def 抓沙发(self):
print(self.名字 + "在抓沙发...")
def 拉屎(self):
print(self.名字 + "在猫砂上拉屎...")


1 = 猫("小黑", "男") # 由于子类没有自己的构造函数`__init__`,就会调用父类的,让实例具备名字性别眼睛数。

1 = 拉屎() # 如果子类没有拉屎的方法就调用父类的,子类有就会调用自己的。(优先看所属的类有没有该方法,没有就往上找父类的同名方法用)

什么时候用继承

1
2
3
"A是B"                             class A(B):
"人类是动物" class 人类(动物):
"新能源车是车" class 新能源车():

示例

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
# 类继承练习:人力系统
# - 员工分为两类:全职员工 FullTimeEmployee、兼职员工 PartTimeEmployee。
# - 全职和兼职都有"姓名 name"、"工号 id"属性,
# 都具备"打印信息 print_info"(打印姓名、工号)方法。
# - 全职有"月薪 monthly_salary"属性,
# 兼职有"日薪 daily_salary"属性、"每月工作天数 work_days"的属性。
# - 全职和兼职都有"计算月薪 calculate_monthly_pay"的方法,但具体计算过程不一样。

class Employee:
def __init__(self, name, id):
self.name = name
self.id = id

def print_info(self):
print(f"员工名字:{self.name},工号:{self.id}")

class FullTimeEmployee(Employee):
def __init__(self, name, id, monthly_salary):
super().__init__(name, id)
self.monthly_salary = monthly_salary

def calculate_monthly_pay(self):
return self.monthly_salary

class PartTimeEmployee(Employee):
def __init__(self, name, id, daily_salary, work_days):
super().__init__(name, id)
self.daily_salary = daily_salary
self.work_days = work_days

def calculate_monthly_pay(self):
return self.daily_salary * self.work_days

zhangsan = FullTimeEmployee("张三", "1001", 6000)
lisi = PartTimeEmployee("李四", "1002", 230, 15)
zhangsan.print_info()
lisi.print_info()
print(zhangsan.calculate_monthly_pay())
print(lisi.calculate_monthly_pay())

文件路径

定位文件的位置可以用两种方法绝对路径和相对路径

绝对路径:从跟目录出发的路径。最后以目标文件或目标目录结尾

  • 在类Unix系统(如Linux和macOS)上,绝对路径通常以 / 开头,例如 /user/home/data/a.py

  • 在Windows系统上,绝对路径通常以驱动器号(例如 D:)开始,然后使用反斜杠 \,例如 D:\Python\a.py

相对路径:从一个参考位置出发。从一个位置来看,其它文件处于什么路径。

当涉及到文件路径时,. 表示当前目录,.. 表示上级目录。以下是这些表示法的示例:

  • /user/home/data/a.py:这是文件 a.py 的绝对路径,从根目录开始,按顺序进入 user 目录、home 目录、data 目录,最后找到文件 a.py
  • ./data/a.py:这是文件 a.py 的相对路径,以当前文件所在的目录为起点,进入 data 目录,最后找到文件 a.py. 表示当前目录。
  • ../..:这是相对路径,表示返回到上两级目录。例如,如果当前目录是 /user/home/,那么 ../.. 将带您返回到根目录 /

文件操作(读)

打开文件:

要操作文件,首先需要使用 open 函数打开它。您可以提供文件的路径,可以是相对路径或绝对路径。

1
open("./data.txt")  # 可以是相对路径或绝对路径

文件打开模式:

open 函数的第二个参数是文件的模式。常见的模式有:

  • "r":读取模式(只读)
  • "w":写入模式(只写)

如果不提供模式参数,默认是读写模式。

1
2
3
open("./data.txt", "r")  # 只读模式
open("./data.txt", "w") # 只写模式
open("./data.txt") # 读写模式

指定编码方式:

可以使用可选参数 encoding 来指定文件的编码方式,这对于处理非英文文本特别有用。

1
open("./data.txt", "r", encoding="utf-8")

文件对象返回:

open 函数执行成功后,将返回一个文件对象,您可以使用该对象进行后续的读取或写入操作。

文件读取方法总结

在文件操作中,我们通常使用以下三种方法来读取文件的内容:

  • read 方法:返回全部文件内容的字符串。
  • readline 方法:返回一行文件内容的字符串。
  • readlines 方法:返回全部文件内容组成的列表。

read 方法

要读取文件的内容,可以使用 read 方法。它会一次性读取文件中的全部内容,并将其作为字符串返回。

如果不想一次性读取整个文件,可以给 read 方法传递一个数字参数,表示要读取的字节数。下一次调用 read 方法将会继续从上次停止的位置读取。

1
2
3
file = open("./data.txt", "r", encoding="utf-8")
content = file.read() # 读取全部内容并存储在变量中
content = file.read(10) #表示会读多少字节,下一次调用就会继续往下读。

readline方法:

使用 readline 方法可以逐行读取文件内容,每次调用只读取一行,并根据换行符判断行的结束。

可以通过判断返回的字符串是否为空来确定是否已经读取到文件结尾。

1
2
3
4
5
file = open("./data.txt", "r", encoding="utf-8")
line = file.readline() # 读取第一行
while line != "": # 判断当前行是否为空
print(line) # 不为空则打印
line = file.readline() # 读取下一行

readlines 方法:

readlines 方法会读取文件的全部内容,并将每行作为列表的元素返回,方便逐行处理。

1
2
3
4
file = open("./data.txt", "r", encoding="utf-8")
lines = file.readlines() # 将每行内容存储到列表中
for line in lines: #一行一行循环列表里的内容
print(line) # 打印当前行

关闭文件

close()方法

文件对象具有 close() 方法,与打开文件的 open 函数相对应。调用 close() 方法后,该文件对象将释放系统资源。务必在每次文件操作结束后关闭文件。

示例:

1
2
3
file = open("./data.txt")
# 执行文件操作
file.close() # 关闭文件

使用 with关键字

with 关键字可自动管理文件的打开和关闭,避免忘记手动关闭文件。在 with 后面使用 open 函数,文件将在缩进的内容执行完毕后自动关闭。

示例:

1
with open("./data.txt") as file:

文件操作(写)

  • 打开文件

    在进行文件写入和读取操作之前,需要使用 open 函数打开文件。通常,写入文件和读取文件都需要打开文件,并在操作完成后关闭文件。

  • 写入文件

    若要写入文件,可以使用 w 模式打开文件。如果目录下没有该文件,程序会自动创建。如果文件已存在,原本文件的内容会被清空。

    示例:

    1
    pythonCopy codewith open("./data.txt", "w", encoding="utf-8") as file:

write 方法

write 方法是用于向已打开的文件对象写入数据的方法。它接受一个字符串参数,并将该字符串的内容写入文件。

  • write 方法的参数应为字符串。
  • write 方法不会自动添加换行符,需要手动添加 \n 来实现换行。
  • 每次调用 write 方法都会将数据写入文件的当前位置。
1
2
3
with open("./data.txt", "w", encoding="utf-8") as file:
file.write("hello!\n") # 向文件中写入"hello!"
file.write("word") # 继续写入"word"

附加模式

如果不想清空文件内容,而是要在文件末尾添加内容,可以使用 a 附加模式。如果文件不存在,程序会自动创建。

示例:

1
2
3
with open("./data.txt", "a", encoding="utf-8") as file:
file.write("hello!\n") # 向文件中写入"hello!"
file.write("word") # 继续写入"word",不会自动换行

读写模式

若要读文件,可以使用 r 模式打开文件。如果需要同时支持读写文件,可以在 r 模式后面加上加号:r+

1
2
3
4
with open("./data.txt", "r+", encoding="utf-8") as file:
file.write("hello!\n") # 向文件中写入"hello!"
file.write("word") # 继续写入"word"
content = file.read() # 读取文件内容

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
# 任务1:在一个新的名字为"poem.txt"的文件里,写入以下内容:
# 我欲乘风归去,
# 又恐琼楼玉宇,
# 高处不胜寒。
with open("./poem.txt", "w", encoding="utf-8") as f:
f.write("我欲乘风归去,\n又恐琼楼玉宇,\n高处不胜寒。\n")

# 任务2:在上面的"poem.txt"文件结尾处,添加以下两句:
# 起舞弄清影,
# 何似在人间。
with open("./poem.txt", "a", encoding="utf-8") as f:
f.write("起舞弄清影,\n")
f.write("何似在人间。")

异常处理

在程序执行过程中,如果某一行代码出现错误,程序会停止执行,后续代码将不会运行。为了更好地处理这些错误情况,我们可以使用异常处理机制。

异常类型

1
2
3
4
5
6
7
8
number_list = [56, 0, 8, 5]
number_list[4] # 索引超出列表范围,引发 IndexError(索引错误)
---------------------------------------------------------------------------
print(56 / 0) # 除以零,引发 ZeroDivisionError(除零错误)
---------------------------------------------------------------------------
open("./data1.txt", "w") # 打开不存在的文件,引发 FileNotFoundError(文件未找到错误)
---------------------------------------------------------------------------
"he" * "hi" # 两个字符串相乘,引发 TypeError(类型错误)

捕捉异常

可以通过try/except语句来捕捉异常,捕捉错误时,从上往下运行。如果第一个except语句就捕捉到了错误,下面的就不会再执行了。

  • try 语句中包含可能引发异常的代码。
  • except 语句用于捕捉特定类型的异常,并在异常发生时执行相应的操作。
  • else 语句包含在没有发生异常时要执行的代码。
  • finally 语句包含无论是否发生异常都要执行的代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try:
user_weight = float(input("请输入您的体重(单位:kg):")) # 放上可能会报错的代码
user_height = float(input("请输入您的身高(单位:m):"))
user_BMI = user_weight / user_height ** 2
except ValueError: # 跟上想捕捉的错误名字,以及冒号。捕捉 ValueError 异常
print("输入不合理数字,请重新运行程序") # 错误发生后执行的操作
except ZeroDivisionError: # 捕捉 ZeroDivisionError 异常
print("身高不能为零,请重新运行程序") # 错误发生后执行的操作
except: # 后面什么都不填会捕捉所有的错误类型
print("发生了未知错误,请重新运行程序") # 错误发生后执行的操作
else:
print("您的BMI值为:" + str(user_BMI)) # 没有发生异常时执行的代码
finally:
print("程序结束运行") # 无论错误与否都会被执行的语句,无论有没有错误,程序炸了,finally里面的内容都会被执行。

python测试

assert语句

assert语句用于在代码中插入断言,以确保某个条件为真。如果条件为假,assert语句将引发AssertionError异常,终止程序执行。这对于验证代码的正确性和调试非常有用。

果求值出来的结果为True,继续运行后面的代码。如果为False,就会产生”断言错误”。一旦出现程序就终止,后面如果有更多的代码就不会执行了。这样并不知道后面的代码里还有哪些其它的错误。

1
2
3
4
assert len("Hi") == 2  # 这会通过,因为字符串"Hi"的长度是2
assert 1 + 2 > 6 # 这会引发AssertionError异常,因为1 + 2不大于6
assert "a" in ["b", "c"] # 这会引发AssertionError异常,因为"a"不在列表中
assert 1 > 3 # 错误的断言,会引发AssertionError异常

unittest库

unittest是Python的标准测试库,用于编写和运行测试。以下是一个简单的示例,展示如何使用unittest测试一个函数:

import unittest引入到测试程序里。一般会把测试代码放到独立文件里进行测试。

这部分实在是不太理解了,仅作为了解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 实现代码    my_calculator.py文件
def my_adder(x, y):
return x + y

---------------------------------------------------------------------------------------------------
# 测试代码 test_my_calculator.py文件

import unittest
from my_calculator import my_adder # from 文件名 impor 函数名或from 文件名 import类名


class TestMyAdder(unittest.TestCase): # 创建一个测试的类,要当unittest.TestCase的子类,这样就可以使用继承自unittest.TestCase的测试功能了。
def test_positive_with_positive(self):
self.assertEquals(my_adder(5, 3), 8)

def test_negative_with_positive(self):
self.assertEquals(my_adder(-5, 3), -2)

unittest.TestCase类

unittest这个python自带的测试库,可以自动找出和运行所有测试用例,一次性给出所有测试结果,并反馈未通过测试的。

unittest.TestCase类里除了assertEqual(A,B)方法外还有其它一些可以测试的方法

1
2
3
4
5
#unittest.TestCase类的常见测试方法
# 方法 #类似于
assertEqual(A,B) assert A==B# 断言A是否等于B。
assertTrue(A) assert A is True # 断言A是否为True。本质上可以代替所有方法,但是不够详细
assertIn(A,B) assert A in B# 断言A是否在B中。

没听懂,大概记一下。

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
# 实现代码 sentence.py
class Sentence:
def __init__(self,sentence):
self.sentence = sentence

#返回句子字母数量
def letter_count(self):
return len(self.sentence)
#返回句子单词数量
def word_count(self):
return len(self.sentence.split(" "))
# 返回所有字母大写后的句子
def upper(self):
return self.sentence.upper()

---------------------------------------------------------------------------
# 测试代码 test_sentence.py
import unittest
from sentence import Sentence
class TestMyAdder(unittest.TestCase):
def setUp(self):
self.sentence = Sentence("hello word!")

def test_str_count(self):
self.assertEquals(self.sentence.str_count(),12)

def test_word_count(self):
self.assertEquals(self.sentence.word_count(),2)

def test_upper(self):
self.assertEquals(self.sentence.upper(),"hello word!")

示例

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 实现代码 shopping_list.py
class ShoppingList:
"""初始化购物清单,shopping_list是字典类型,包含商品名和对应价格
例子:{"牙刷": 5, "沐浴露": 15, "电池": 7}"""
def __init__(self, shopping_list):
self.shopping_list = shopping_list

"""返回购物清单上有多少项商品"""
def get_item_count(self):
return len(self.shopping_list)

"""返回购物清单商品价格总额数字"""
def get_total_price(self):
total_price = 0
for price in self.shopping_list.values():
total_price += price
return total_price
----------------------------------------------------------
# 测试代码 test_shopping_list.py

'''
注意:此文件是针对以下类的测试文件。
你可以在此文件同一文件夹下新建shopping_list.py,并复制以下内容到该文件:

class ShoppingList:
"""初始化购物清单,shopping_list是字典类型,包含商品名和对应价格
例子:{"牙刷": 5, "沐浴露": 15, "电池": 7}"""
def __init__(self, shopping_list):
self.shopping_list = shopping_list

"""返回购物清单上有多少项商品"""
def get_item_count(self):
return len(self.shopping_list)

"""返回购物清单商品价格总额数字"""
def get_total_price(self):
total_price = 0
for price in self.shopping_list.values():
total_price += price
return total_price
'''

import unittest
from shopping_list import ShoppingList

class TestShoppingList(unittest.TestCase):
def setUp(self):
self.shopping_list = ShoppingList({"纸巾": 8, "帽子": 30, "拖鞋": 15})

def test_get_item_count(self):
self.assertEqual(self.shopping_list.get_item_count(), 3)

def test_get_total_price(self):
self.assertEqual(self.shopping_list.get_total_price(), 55)


高阶函数

函数是可以被传入函数的,这种把函数作为参数的函数称为高阶函数。请注意,当作参数的函数是直接用函数名进行传入,表示函数本身,后面不要有括号或参数。

1
2
calculate_and_print(3, calculate_square  #没有括号代表函数本身
calculate_and_print(3, calculate_square()) #有括号则返回函数调用后返回的结果

你还可以将格式化函数作为高阶函数的参数传入。这意味着你可以将一个函数用作另一个函数的工具,让代码更加灵活。

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 打印平方
def calculate_and_print(num):
result = num * num # 计算
print(f"""
丨数字参数丨 {num}
丨计算结果丨 {result}丨""")# 打印


calculate_and_print(3)# 传入数字

-----------------------------------------------------------------------
#除了打印平方,还打印三次方。
def calculate_and_print(num,power):
if power == 2:
result = num * num # 计算平方
elif power == 3:
result = num * num * num # 计算三次方

print(f"""
丨数字参数丨 {num}
丨计算结果丨 {result}丨""")# 打印


calculate_and_print(3,3)# 传入数字和打印选项

----------------------------------------------------------------
# 除了打印三次方还能打印某数字+10后的结果
# 不把计算的过程逻辑保留着函数中,而把计算的函数作为参数。
def calculate_and_print(num, calculator):
result = calculator(num)
print(f"""
丨数字参数丨 {num}
丨计算结果丨 {result}丨""") # 打印


def calculate_square(num): # 计算平方
return num * num


def calculate_cube(num): # 计算三次方
return num * num * num


def calculate_plus_10(num): # 计算+10
return num + 10


calculate_and_print(3, calculate_square) # 计算打印平方,就传入平方函数
calculate_and_print(3, calculate_plus_10) # 计算+10就传入+10的函数
--------------------------------------------------------------------------------------------------
# 定义一个函数 calculate_and_print,接受三个参数:num(数字参数)、calculator(计算函数)、formatter(格式化函数)
def calculate_and_print(num, calculator, formatter):
# 使用计算函数来计算结果,并将结果保存在变量 result 中
result = calculator(num)

# 使用格式化函数来格式化并打印数字参数和计算结果
formatter(num, result)


# 定义一个格式化函数 print_with_vertical_bar,接受两个参数:num(数字参数)和 result(计算结果)
def print_with_vertical_bar(num, result):
# 打印数字参数和计算结果,使用竖线丨进行装饰
print(f"""
丨数字参数丨 {num}
丨计算结果丨 {result}丨""")


# 定义一个计算函数 calculate_square,用于计算数字的平方
def calculate_square(num):
return num * num


# 定义一个计算函数 calculate_cube,用于计算数字的三次方
def calculate_cube(num):
return num * num * num


# 定义一个计算函数 calculate_plus_10,用于将数字加上 10
def calculate_plus_10(num):
return num + 10


# 调用 calculate_and_print 函数,传入数字 3、计算函数 calculate_square 和格式化函数 print_with_vertical_bar
calculate_and_print(3, calculate_square, print_with_vertical_bar) # 计算打印平方,就传入平方函数

匿名函数

匿名函数,也称为Lambda函数,适用于那些不常用、仅需一次性使用的函数。Lambda函数不需要命名,可以在需要时立即定义和使用。

定义Lambda函数的方式如下:

1
lambda num1, num2: num1 + num2

Lambda函数可以作为高阶函数的参数传递,调用方式与普通函数相同,但需要使用括号将Lambda函数括起来,以表示它是一个整体。

1
(lambda num1, num2: num1 + num2)(2,3)# 调用方式和普通函数一样,唯一的区别是前面的匿名函数也需要括号括住,表示是一个整体。

需要注意的是,Lambda函数有一定的局限性,它的主体部分只能包含单个语句或表达式,适用于相对简单的情况。如果需要包含多个语句或更复杂的逻辑,应该使用普通的函数定义。

1
2
3
4
5
6
lambda  num1, num2: num1 + num2# 只能有一个语句/表达式
-------------------------------------------------------------------------
def calculate_sum(num1, num2):# 可以有多个语句/表达式
print(num1)
print(num2)
return num1 + num2
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
# 定义一个函数 calculate_and_print,接受三个参数:num(数字参数)、calculator(计算函数)、formatter(格式化函数)
def calculate_and_print(num, calculator, formatter):
# 使用计算函数来计算结果,并将结果保存在变量 result 中
result = calculator(num)

# 使用格式化函数来格式化并打印数字参数和计算结果
formatter(num, result)


# 定义一个格式化函数 print_with_vertical_bar,接受两个参数:num(数字参数)和 result(计算结果)
def print_with_vertical_bar(num, result):
# 打印数字参数和计算结果,使用竖线丨进行装饰
print(f"""
丨数字参数丨 {num}
丨计算结果丨 {result}丨""")


# 定义一个计算函数 calculate_square,用于计算数字的平方
def calculate_square(num):
return num * num


# 定义一个计算函数 calculate_cube,用于计算数字的三次方
def calculate_cube(num):
return num * num * num


# 定义一个计算函数 calculate_plus_10,用于将数字加上 10
def calculate_plus_10(num):
return num + 10


# 调用 calculate_and_print 函数,传入数字 3、lambda 函数(计算数字乘以 5),和格式化函数 print_with_vertical_bar
calculate_and_print(3, lambda num: num * 5, print_with_vertical_bar) # 计算数字乘以 5,然后使用格式化函数打印

数据分析准备


未完结!