文章目录
- 函数分为内置函数和外置函数,像print这样经常会使用的函数是内置函数,所以不需要导入库,但是有些需要导入别的库,是外部函数
- 查找文档:python标准库不全?是的,这是官方的文档,没有第三方的模块,数量更庞大并且多样。第三方库
- 本笔记根据b站的up主林粒粒呀教学视屏整理而成
print("666")
#字符串连接
print("Hello"+" World")
#字符串中的引号:利用转义符”\“
print("He said \"Let \'s go!\"")
#每个print默认另其一行,也可以用\n
#''' '''三引号,把文本内容自动换行输出
print('''君不见,黄河之水天上来,奔流到海不复回
君不见,高堂明镜悲白发,朝如青丝暮成雪''')
变量名
- 先存再操作,变量不能有空格不能以数字开头,由字母数字下划线组成
- python的变量和C++不一样,python没有int num这样的提前声明类型,可以直接使用num=None进行声明,或者直接num=0赋初值。
- 约定的命名方法:下划线命名法:1.字母全部小写 2.下划线分割不同单词比如user_age
- 变量名大写敏感,Use_age和use_age是不同的变量
greet="你好,吃了吗?"
print(greet)
关键字
不适用于命名变量:
运算符
- 按优先级:
() 括号
**(乘方)
*(乘)
/(除)
/+ (加)
/-(减) - //(除完向上取整)
- 计算的外部函数库math,在文件最开始一行导入方法import math
math文档
应用:
x 2 + 9 x + 20 x^2+9x+20 x2+9x+20
import math
a=1;b=4;c=3
(-b+(b**2-4*a*c)**(1/2))/2#只是将结果计算出来,并没有任何输出和保存
(-b-math.sqrt(b**2-4*a*c))/2
print((-b-math.sqrt(b**2-4*a*c))/2)
print((-b+math.sqrt(b**2-4*a*c))/2)
注释
- 计算机不会执行,用于自己看
- 拥有快捷键ctrl+‘/’
- ”“” “”“三个双引号多行注释
数据类型
- 字符串str
str="hello\n"
#统计长度
print(len(str))#\n只会统计一个长度
#提取字符串的单个字符,[]中放索引,从0开始
print("Hello"[0])
#输出最后一个
print("Hekko"[-1])
- 整型int
- 浮点数float
a=true
b=false
- 布尔型bool
- 空值类型 NoneType
#只有一种值None,表示完全没有值,不代表任何值和类型,N需要大写
My_nuni=None
#使用type()返回数据类型
print(type(My_nuni))
- 列表
- 字典
命令行模式
- 交互模式:读一行执行一行,不需要创建任何文件,不需要print就可以看到结果,所有输入指令都不会被保存。
input
#input括号里可以放一些提示信息,input只会返回字符串
user_age=input("请输入用户的年龄:")
#直接进行运算显然是不对的,那咋么办呢
#可以使用int() float() double() str();但要确保确实可以转化
#比如L,特殊字符,是不可以直接使用int()转化的
test_int=int(input("请输入测试字符:"))
print(test_int)
#BMI=体重/(身高**2)
user_weight=float(input("请输入您的体重(单位kg):"))
user_height=float(input("请输入您的身高(单位:m):"))
user_BMI=user_weight/user_height**2
print("您的BMI值为:"+str(user_BMI))
if语句
##################if bool变量: ##############is_happy=True
if is_happy:
print('I\'m happy')
#可以用一些比较运算符来进行更为复杂的判断
#(==)(!=)(>)(>=)(<)(<=),数字之间可以比较,字符之间可以比较
#缩进一般为四个空格一次缩进
#实践:用if判断今晚能不能打游戏
#注意缩进是很重要的
mood_index=int(input("对象今晚的心情指数是:"))
if mood_index>=60:
print("恭喜,今晚应该可以打游戏,去吧皮卡丘!")
else:
print("糟糕,今晚不能打游戏")
##########嵌套条件语句:根据缩进进行判断##############
#mood_index是0-100之间的整数
#is_at_home是bool值
is_at_home=bool(int(input("女朋友在家吗?:")))
##当使用Bool(),除了数字0之外的所有都会返回True啊啊
if mood_index<60:
if is_at_home:
print("放弃游戏低调做人")
else:
print("自由")
########多个条件判断###############################
#实现BMI对应的身体体重状况判断:
#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:
print("此BMI值属于偏瘦范围。")
elif 18.5<user_BMI<=25:
print("此BMI值属于偏瘦范围")
elif 25<user_BMI<=30:
print("此BMI属于偏胖范围")
elif user_BMI>30:
print("此BMI属于肥胖范围")
逻辑运算
- and or not(只能对一个变量操作)
- 可以使用括号改变优先级
house_work_count=None
res_envelope_count=None
shopping_count=None
has_been_angry=None
if (house_work_count>10 and res_envelope_count > 1 and shopping_count>4 and not has_been_angry):
print("摩拳擦掌等待Swith")
else:
print("Swith随风散去")
数据结构之列表
######列表的定义
shopping_list=["键盘","键帽"]
######给列表的最后加上一个元素
#shopping_list.append()是方法,与函数的使用有很大的不同,函数的使用是len(shopping_list)
shopping_list.append("显示器")
#####数据结构和变量有着很大的不同,数据结构是可以用方法改变内容,变量只能重新赋值
#对变量来说不可变
s="hello"
print(s.upper())#把原来的字符全部变为大写
s=s.upper()#要想改变s中的大小写要重新赋值
#对列表来说可变
shopping_list.append("空调")
shopping_list.remove("显示器") #并没有执行赋值的操作但是已经改变了
#remove在使用时,要删除的变量要确确实实存在于列表中,不然会报错
print(shopping_list) #查看列表元素
#python的列表可以放不同数据类型的元素
list1=["hello",66,66.6,True,None]
print(list1)
print(len(list1)) #也可以通过len函数获得长度
print(shopping_list[0]) #也可以通过索引获取某个值
#直接利用索引修改某个值
list1[1]="音响"
num_list=[1,13,-7,2,96]
print(max(num_list)) #返回num_list中最大的元素
print(min(num_list)) #返回num_list中最小的元素
print(sorted(num_list)) #不改变原来列表的顺序,返回按从小到大排列的数据
数据结构之字典
########字典基本组成元素是键值对 键:值
#空字典
contacts={}
contacts={"小明":"1370000000","小花":"1750000000"}
#获取某个键的值
contacts["小明"]
########键的类型是不可变的
#可变的:列表
#不可变的:字符串str 整型int 浮点数float 布尔类型bool
#对于键可能重复的,但是又不能用可变的数据,python贴心的准备了元组作为键
example_tuple=("键盘","键帽") #元组可以放若干个元素,但是不可变
########字典和列表一样,也可以进行改变
contacts={'小明':"13700000","小花":"137000000"}
#增加元素或者更新值(键已经存在就更新值,不存在就添加键值对)
contacts["齐博涵"]="13752516461"
contacts["小明"]="ok"
print(contacts)
#看一下某个键是否已经存在
print("小明" in contacts) #返回的是bool值
#删除键值对用del
del contacts["小明"] #键不存在就会报错
#也可以用len返回长度
print(len())
#返回字典所有键
contacts.key()
#返回字典所有值
contacts.values()
#返回所有键值对
contacts.items()
########结合input、字典、if判断做一个查询流行语含义的电子词典流程
slang_dict={"依法治国":"法治是治国理政的基本方式,也是持续增进民生福祉的重要保障。",
"就业":"在历次全国两会调查中,“社会保障”一直备受关注,曾19次进入十大热词榜单。"}
slang_dict["乡村振兴"]="在今年全国两会调查中,“乡村振兴”位居热词榜前三。"
query=input("请输入您想要查询的流行语")
if query in slang_dict:
print("您查询的"+query+"含义如下")
print(slang_dict[query])
else:
print("您查询的流行语暂未收入")
print("当前的收入流行语为"+str(len(slang_dict)+"条"))
for循环
#######for循环中可以对列表、字典、字符串等进行迭代
#对列表进行迭代,是对每个元素操作;字典是每个键和对应的值;对字符串进行迭代,按顺序对字符做事情
#基本结构:
#对列表循环
temperature_list=[36.4,36.6,36.2,37.0,38,37.3,36.5,38,36.9]
for temperature in temperature_list:
#对每个变量的事情
if temperature>=38:
print("有人发烧了")
#对字典循环
temperature_dict={"111":36.4,"112":36.6,"113":36.2,"114":38}
for staff_id,temperature in temperature_dict.items():
#这种赋值会把items返回的元组的第一个值给staff_id,第二个值给temperature
if temperature>=37.3:
print(staff_id)
#range生成整数数列用于循环:
for i in range(1,10):#范围是a~b-1
print(i)
#步长为2的range
for num in range(1,10,2):
print(num)
for num in range(5,10,2):
print(num)
#只放一个起始值默认为0,步长默认为1
for num in range(20)
print(num)
#高斯做的小学题
total=0;
for i in range(1,101):
total=total+i
print(total)
while条件循环
#while 循环
#measure_brighrness函数返回当前测量天空的亮度
while measure_brightness()>=500:
#拍照片
take_photo()
#逐个打印list1中的元素
list1=["你","好","吗","兄","弟"]
for char in list1: #逐个字符打印
print(char)
for i in range(len(list1)): #range只输入了一个值默认从0开始
print(list1[i])
i=0
while i<len(list1): #需要一个额外的变量来控制循环的次数
print(list1[i])
i=i+1
##没有条件上的特殊要求,for是很简单循环,而且不用判断,只是遍历
#简单的计算平均值的计算器:
print("哈喽呀,我是一个求平均值的程序。")
total=0
count=0
user_input=input("请输入数字(完成所有的数字输入后,请输入q终止程序):")
while user_input !="q" and user_input!="Q" :
count += 1
total += float(user_input)
user_input=input("请输入数字(完成所有数字输入后,请输入q终止程序):")
if count==0:
result="未输入"
else:
result=total/count
print("平均数是:"+str(result))
字符串的操作format,f-字符串
###新年给联系人发送短信,要给每个短信加名字,显得不是群发,假设有一个send_message函数
contacts=["老余","老林","老陈","老李","老赵","老杜","老娄"]
for name in contacts:
message_content=("春风得意马蹄疾,新年伊始送祝福。愿"+ name +"在新的一年里,事业有成步步高,财源广进福气绕"
"身体健康心情好,家庭和睦乐陶陶。祝你新年快乐,万事如意!")
print(message_content)
#send_message(name,message_content)
###如果想要更加详细的加上更多信息:
contacts=["老余","老林","老陈","老李","老赵","老杜","老娄"]
year="虎"
for name in contacts:
message_content="""
绿回春渐,心愿肇启。
新岁甫至,福气东来。 金"""+year+"""贺岁,欢乐祥瑞。
金"""+year+"""敲门,五福临门。
给"""+name+"""及家人拜年啦!
新春快乐,"""+year+"""年大吉!"""
print(message_content)
# send_message(name,message_content)
###上面的字符串表达十分不美观,而且momo错,采用format方法
contacts=["老余","老林","老陈","老李","老赵","老杜","老娄"]
year="虎"
for name in contacts:
message_content="""
绿回春渐,心愿肇启。
新岁甫至,福气东来。 金{0}贺岁,欢乐祥瑞。
金{0}敲门,五福临门。
给{1}及家人拜年啦!
新春快乐,{0}年大吉!""".format(year,name)
#0,1是索引
print(message_content)
# send_message(name,message_content)
###采用format方法2
contacts=["老余","老林","老陈","老李","老赵","老杜","老娄"]
year="虎"
for name in contacts:
message_content="""
绿回春渐,心愿肇启。
新岁甫至,福气东来。
金{current_year}贺岁,欢乐祥瑞。
金{current_year}敲门,五福临门。
给{recevier_name}及家人拜年啦!
新春快乐,{current_year=year}年大吉!""".format(current_year=year,recevier_name=name)
#这种方式等号前面是关键字,等号后面是值,字符串中是关键字,会根据有关键字去寻找值
print(message_content)
# send_message(name,message_content)
###f-字符串
contacts=["老余","老林","老陈","老李","老赵","老杜","老娄"]
year="虎"
for name in contacts:
message_content=f"""
绿回春渐,心愿肇启。
新岁甫至,福气东来。 金{year}贺岁,欢乐祥瑞。
金{year}敲门,五福临门。
给{name}及家人拜年啦!
新春快乐,{year}年大吉!"""
print(message_content)
# send_message(name,message_content)
#使用format方法不需要手动将数字转化为字符串,format帮我们解决
gpa_dict={"小明":3.251,"小花":3.869,"小李":3.782,"小张":3.652}
for name,gpa in gpa_dict.items():
print("{0}你好,你的当前绩点为:{1:.2f}".format(name,gpa))
#{1:.2f}可以用来指定保留几位小数
函数
DRY原则:Don’t repeat yourself
不重复单调的代码
########以计算扇形面积为例:
###定义一个函数:
def calculate_sector_1(): #def 函数名()
#接下来是一些定义函数的代码
central_angle_1=160
radius_1=30
sector_area_1=central_angle_1/360*3.14*radius_1**2
print(f"此扇形的面积为:{sector_area_1}")
#只有被调用时才会执行,执行代码如下:
calculate_sector_1()
###上面的函数只能计算扇形1的面积
##可以通过函数的参数传递进行更加通用的计算
def calculate_sector(central_angle, radius): #def 函数名()
#接下来是一些定义函数的代码
sector_area=central_angle/360*3.14*radius**2
print(f"此扇形的面积为:{sector_area}")
calculate_sector(160,30)
##每个变量都有作用域,作用域就是这个变量存在可以被调用的范围,在函数中的变量在函数之外无法调用。
##这就需要函数有返回值,才可以在函数之外保留函数的调用结果
#BMI计算为例子:
def calculate_BMI(user_weight,user_height):
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:
print("此BMI值属于偏瘦范围。")
elif 18.5 < user_BMI <= 25:
print("此BMI值属于偏瘦范围")
elif 25 < user_BMI <= 30:
print("此BMI属于偏胖范围")
elif user_BMI > 30:
print("此BMI属于肥胖范围")
return user_BMI
result=calculate_BMI(80,1.8)
print(result)
调用已存在的函数
不要重复造轮子,别人已经做好的直接奶来用
python标准库
- 但是内置函数有限,这时目光转向python库的其他模块,模块就是python程序,引入模块后,里面的变量和函数都可以调用使用。
- 以求取中位数为例子
#自己手撸代码:
def median(num_list):
sorted_list=sorted(num_list)
n=len(num_list)
#如果奇数个,取中间那个
if n%2==1:
return sorted_list[n//2]
#如果一共有偶数个数字,取中间两个数的平均值
else:
return(sorted_list[n//2-1]+sorted_list[n//2])/2
#0 1 2 3 4 5 6 7中间的位置是3和4
print(median([69,124,-32,27,217]))
num_list=[2,5,9]
print(median(num_list))
from statistics import median
import statistics
num_list=[2,5,9]
print(median(num_list))
print(statistics.median(num_list))
- from 库 import /* 库里所有函数调用时不再需要模块名:不推荐使用,面临函数名冲突风险。
- import 库,需要模块名.函数名()。
- from 库 import 函数名,用这个函数时不再需要模块名。
面向对象
- 面向过程是完成某个具体问题的代码,基本可以理解为函数,核心是把要实现的东西拆分成一个又一个的步骤依次完成,核心是把内容拆分成一个一个的模块,但有时候对象的需要属性过多,不容易分辨
- 面向对象编程,最重视的不是过程,而是模拟真实世界,构建每个对象的性质,然后面向每个对象的性质去发掘每个对象可以解决的问题。
- 面向对象编程重要的是创建出类,再用类去定义对象。
- 有对象很大的好处是可以直接传递对象,对象会带着自己的属性,使得编程的逻辑更加清晰,这样避免了复杂的传输问题。
- 对象还可以绑定方法,方法对应对象可以做些什么。
- 属性就是放在类里面的变量,方法就是放在类里面的函数
- 结构:只是描述
class 洗衣机
def __ init __ (self,容量):
self.容量=容量
def 清洗(self,需要清洗的物品):
# 通过容量计算烘干的时长,在一个类里,self的属性变量不再需要传参
洗衣机容量=self.容量 - 面向对象的三特性:封装,继承,多态
封装:写类的人将内部实现细节隐藏起来,使用类的人,只通过外部接口访问和使用,接口可以被大致理解为提供使用的方法。
继承:面向对象编程允许创建有层次的类,就像现实中的儿子继承爸爸,爸爸继承爷爷,可以有子类和父类来表示从属关系,父类的属性和方法都可以被继承;
多态:同样的接口因为对象不同,但是有不同的方法;比如都是学生的子类:小学生和大学生,但是有不同的写作业方法 - 面向对象和面向过程谁有谁劣还需要具体的场景。
#定义ATM类
class ATM:
def __init__(self,ID,Bank,subBank):
self.ID=ID
self.Bank=Bank
self.subBank=subBank
#创建两个ATM对象
atm1=ATM("001","招商银行","南园支行")
atm2=ATM("002","中国银行","北园支行")
print(atm1.ID)
封装:自定义类
- 自己定义类以及属性
- 类的命名法与普通变量的下划线命名法不同,采用Pascal命名
UserAccount变量名的没单词首字母大写来分割单词。 - 自己定义类(class 类名:)以及属性(def init(self,…,…)😃
#自己定义类(class 类名:)以及属性(def __init__(self,..,..):)
#不传参创建对象的属性
class CuteCat:
def __init__(self):
self.name="Jojo"
cat1=CuteCat()
print(cat1.name)
#传参创建对象和属性
class CuteCat:
def __init__(self,name,age,color):
self.name=name
self.age=age
self.color=color
cat1=CuteCat("Jo")
print(cat1.name)
#self.name的name是属性,括号里的name是参数
- 自己定义类的函数(def 函数名())
class CuteCat:
def __init__(self,name,age,color):
self.name=name
self.age=age
self.color=color
def speak(self):
#方法里也有self,为了使方法可以借用或者修改属性
print("喵"*self.age)
def think(self,content):
print(f"小猫{self.name}在思考{content}...")
#输出对象的属性
cat1=CuteCat("Jo",3,"黄色")
print(cat1.name)
#调用对象的方法,和函数调用并没有太大差距
cat1.speak()
cat1.think("黄色")
实践
#定义一个学生类
#要求:
#1.属性包括:学生姓名,学号,以及语数英三科的成绩
#2.能够设置某科目的成绩
#3.能够打印出该学生所有的科目成绩
class Student:
def __init__(self,name,ID,language_mask,english_mask,math_mask):
self.name=name
self.ID=ID
self.grade={"语文":language_mask,"英语":english_mask,"数学":math_mask}
def print_grade(self):
# print(f"""
# 姓名:{self.name}
# 学号:{self.ID}
# 语文成绩:{self.grade["语文"]}
# 英语成绩:{self.grade["英语"] }
# 数学成绩:{self.grade["数学"] }""")
print(f"学生:{self.name}(学号:{self.ID}的成绩为:)")
for course in self.grade:
print(f"{course}: {self.grade[course]}")
def change_grade(self,course,grade):
if course in self.grade:
self.grade[course]=grade
else:
print("课程名称错误")
qibohan=Student("齐博涵","24155","98","10","99")
qibohan.print_grade()
qibohan.change_grade("英语","100")
qibohan.print_grade()
继承
- 继承:面向对象编程允许创建有层次的类,就像现实中的儿子继承爸爸,爸爸继承爷爷,可以有子类和父类来表示从属关系,父类的属性和方法都可以被继承;
- 举例:下图的两个类有公共部分,创建一个父类
#创建一个哺乳动物的父类
class Mammal:
def __init__(self,name,sex):
self.name=name
self.sex=sex
self.num_eyes=2 #因为眼睛固定了,就俩,不用传参了
def breath(self):
print(self.name+"is breathing...")
def poop(self):
print(self.name+"is shitting...")
#子类没有定义的属性和呼吸拉屎时,会调用父类的方法
#子类有的属性和方法,有限使用子类
class Human(Mammal): #括号里写父类的名字
def __init__(self,name,sex):
super().__init__(name,sex) #这里会返回父类init
self.has_tail=False
def red(self):
print(self.name+"is reading...")
class Cat(Mammal):
def __init__(self, name, sex):
super().__init__(name, sex) # 这里会返回父类init
self.has_tail = True #False和True的首字母必大写
def scratch_sofa(self):
print(self.name+"is scrathing the sofa...")
qibohan=Human("齐博涵","女")
qibohan.breath()
qibohan.red()
qibohan.poop()
- 什么时候用子类?当然是有子集的时候
class Employee:
def __init__(self,name,id):
self.name=name
self.id=id
def print_info(self):
print("姓名:"+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):
print("姓名:"+self.name+" 工号:"+self.id+" 月工资是:"+str(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):
print("姓名:"+self.name+" 工号:"+self.id+" 月工资是:"+str(self.daily_salary*self.work_days))
qibohan=FulltimeEmployee("齐博涵","2542",10000)
qibohan.print_info()
qibohan.calculate_monthly_pay()
qibohan=ParttimeEmployee("齐博涵",'2542',300,20)
qibohan.print_info()
qibohan.calculate_monthly_pay()
文件操作
文件的定位
- 类Unix操作系统(Linux、macOS等),目录结构橡树跟一样,有一个根目录,一般用\表示,一切的节点都存存放在这个根目录下。
- Windows系统就不一样,每个磁盘分区都有自己的根目录,用分区名:\表示
- 前两者定位文件目录的方法有绝对路径和相对路径:
- 绝对路径:从根目录出发的路径,因为以根目录为基准,对类Unix操作系统,绝对路径就是类似:”/home/data/a.py“。Windows系统:”C:\Users\OKl\a.py“
- 相对路径:就是从它表示的位置上来看,其他文件处于什么位置:用.表示当前参照文件所在的目录,用…表示更上一层楼的父目录;再更上一层楼就用… \(or / ) …进行分割:Windows用\,Unix用/;再往上还是用分隔符分割。在同一目录下,可以直接写,省略…
文件的读取
- 打开目标文件:
f=open(“相对路径(or绝对路径)”,”打开方式“,encoding=“utf-8”)
- utf-8是选择了文件的读取方式为utf-8编码,是unicode的编码,汉字编码官方文档。
- “r ”读取模式(只读)
- ”w“ 写入模式
- open函数返回一个文件读取对象,后续可以针对其继续进行操作
- 文件不存在或路径错误爆:FileNotFoundError
- f.read() # read方法,调用后会一次性读取文件里面的所有内容,并以字符串的形式进行返回,读文件喜欢txt这样的纯文本
- 调用完read后再调用read会返回空,因为文件的指针会记录读到哪个位置了,第一次调用文件的指针已经指空了。
- 文件很大的时候不要用read,因为很占内存,甚至挤爆,可以采用f.read(10),读十个字节;
- 读到结尾返回空字符串
- f.readline()每次会读取文件的一行,以每行结尾的\n进行判断本行是否结束
- 读到结尾返回空字符串
f=open("data.txt","r")
line=f.readline()
while line!=""
print(line)
line=f.readline()
5.f.readlines() 会读取全部的文件内容,并返回由每行组成的字符串列表
f=open("data.txt","r",encoding="utf-8")
lines=f.readlines()
for line in lines #遍历每一行
print(line)
- 读取文件后,关闭文件
- 手动释放
f=open("data.txt")
print(f.read())
f.close()
- 自动释放
with open("data.txt") as f:
print(f.read()) #对文件操作结束后就会释放
文件写入
- 首先要进行文件打开,如果文件不存在,会创建一个文件,如果原文件已经存在,打开之后会清空进行重写;不支持读文件内容操作。
with open("./data.txt","w",encoding=”utf-8") as f:
f.write("Hello!\n")
f.write("Yoooo")
- 如果文件原来已经存在,那就使用“a”方式打开参数,这样就能在文件已有的数据后面追加写入,如果文件不存在,也会创建一个文件;不支持读文件内容操作
with open("./data.txt","a",encoding="utf-8") as f:
f.write("yoooo\n")
- 采用“r+”的方式打开文件后,就可以对文件进行读写操作
with open("./data.txt","r+",encoding="utf-8") as f:
print(f.read())
f.write("hello!",encoding="utf-8")
程序BUG
程序异常的类型
- 列表超过索引时会出现:IndexError
- 数字除以0时会产生ZeroDivisionError
- 打开的文件不存在时:FileNotFoundError
- 两个字符串做乘法会产生TypeError
捕捉异常
try:
user_weight=float(input("请输入您的体重:(kg)"))
user_height=float(input("请输入您的身高:(m)"))
user_BMI=user_weight/user_height**2
except ValueError:
print("输入为不合理数字,请重新运行,并输入正确的数字。") #程序错误时按照类型往下执行
except ZeroDivisonError:
print("身高不能为0,请重新运行,并输入正确的数字。")
except:
print("发生未知错误") #
else:
print("您的BMI为:"+str(user_BMI)) #程序不报错误时执行
finally:
print("ok了家人们") #无论程序是否错误都会执行
测试
#assert语句后面跟bool类型,如果为False那么就会跳出AssertError
assert 1+2>6
#但是assert后面的语句不会执行,因此采用专门的测试库:unittest
#unitest是内置的库
#通常把要实现代码和测试代码放在独立的文件库里,方便区分
#被测试文件中,文件名:mygod:
def my_adder(x,y):
return x+y
#测试文件中
import unittest
#from mygod import my_adder
#创建一个测试的类:
class TestMyAdder(unittest.TestCase):#是unitest.TestCase的子类
def test_positive_with_positive(self):
#每个一方法的命名必须以test_开头,unittest这个库会自动检索test_开头的方法,并作为测试函数
#预先设计好输入和预计输出
self.assertEquals(my_adder(5,3),8)
#如果相等显示测试通过,不相等显示测试不通过,但程序也不会炸
def test_negative_with_negative(self):
self.assertEquals(my_adder(-5,-3),-8)
##测试方法:在终端输入:python -m unittest
##就会检索子类中所有以test_开头的方法,并运行,展示测试的结果
##会展示测试成功“..”一个点代表一个测试函数通过。
##如果测试函数不通过会给出”F“,一个“F”代表一个测试结果不通过,还会给出具体是哪个测试函数没有通过
高效的找出BUG
- unitest.TestCase类常用的测试方法
import unittest
A=1;B=1;C=[1,2]
class TestMyAdder(unittest.TestCase): # 是unitest.TestCase的子类
def test_metheds(self):
##A==B
self.assertEquals(A, B)
##assert A is true
self.assertTrue(A)
##assert A in B
self.assertIn(A,C)
##assert A!=B
self.assertNotEquals(A,B)
##assert A is False
self.assertFalse(A)
##assert A not in B
self.assertNotIn(A, C)
- 每次执行以test_开头的测试方法之前都会运行一次setUp属性,一些必须在每个测试方法中都执行的代码,可以放到这里。
![[setUp方法.png]]
实践环节
###实践环节:
##实际代码
class ShoppingList:
"""初始化购物清单,shopping_list是字典类型,包含商品名和对应的价格
例子:{"牙刷":5,”沐浴露“:15}"""
def __init__(self,shopping_list):
self.shopping_list=shopping_list
#返回购物清单上有多少项商品
def get_item_cout(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
##测试代码
#在这里所以直接进行测试,如果在别的文件要:from 文件名 import ShoppingListimport unittest
class TestShoppingList(unittest.TestCase):
def setUp(self):
self.shopping_list=ShoppingList({"纸巾":4,"帽子":30})
def test_get_item_count(self):
self.assertEqual(self.shopping_list.get_item_cout(),2)
def test_get_total_price(self):
self.assertEqual(self.shopping_list.get_total_price(),34)
高阶和匿名函数
- 把函数作为传入参数的函数作为高阶函数,传入时只把函数名传入,后面不带括号和参数,etc:calculate_and_print(3,calculate_square),calculate_square是函数名;
def calculate_and_print(num,calculator,formatter):
result=calculator(num)
formatter(num,result)
def print_with_vertival_bar(num,result):
print(f"""
|数字参数|{num}|
|计算结果|{result}|""")
def calculate_square(num):
return num*num
def calculate_cube(num):
return num*num*num
def calculate_plus_10(num):
return num+10
def calculate_times_5(num):
return num*5
calculate_and_print(7,calculate_times_5,print_with_vertival_bar)
- 匿名函数:不需要起名字,随用随仍,匿名函数举例:lamba num1,num2:num1+num2。lmabda是匿名函数的关键字,num1num2是参数,用逗号隔开,冒号后面是计算式。
- 匿名函数只能有有一个表达式。