(一)字符串
1.常识
+:连接两个字符串
\:换行写,表示字符串未结束(用于字符串太长)要缩进
print:默认在结尾换行,如果不想换行可加上end=""
a="hello"+"\t"+"world"
print(a)
#==>hello world
b='123'\
'456'
print(b)
#==>123456
a='abcd'
b='efg'
print(a,end='')
print(b)
#==>abcdefg
2.大小写函数
.title():单词首字母大写
.upper():全大写
.lower():全小写
.capitalize():字符串第一个字母大写
a="helLO wOrld"
a1=a.title()
a2=a.upper()
a3=a.lower()
a4=a.capitalize()
print(a1)
print(a2)
print(a3)
print(a4)
'''
a1="Hello World"
a2="HELLO WORLD"
a3="hello world"
a4="Helow world" #注意与a1的区别
3.删除字符串首末多余空格
.rstrip():删除右空格
.lstrip():删除左空格
.strip():删除空格
a=" print "
a1=a.rstrip()
print(a1)
#==>" print"
a2=a.lstrip()
print(a2)
#==>"print "
a3=a.strip()
print(a3)
#==>"print"
字符串可以用单引号和双引号
'print’和"print"打印结果相同
注意引号匹配
4.其他常用函数
.endswith():以什么字符串结尾
.count():得到某字符的个数(不一定是单字符)
.find():返回从左第一个制定字符的索引,找不到返回-1
.index():返回从左第一个指定字符的索引,找不到报错
.split():按照指定的内容分割字符串(以列表形式)
.replace( 替换前, 替换后, [替换个数]):从左到右替换指定的元素,可以指定替换的个数,默认全部替换(但字符串未变)
eval():清除输入文字两端的字符串,常与input搭配使用
#endswith:
list_string = ['apple','banana_pr','orange','cherry_pr']
for fruit in list_string:
if fruit.endswith('pr'):
print(fruit)
#==>['banana_pr','cherry_pr']
#count:
string = 'abcdaabb'
num1=string.count('a')
num2=string.count('ab')
print(num1)
print(num2)
'''==>
3
2
'''
#find和index:
string= 'hello_world'
print(string.find('e'))
print(string.index('e'))
print(string.find('c'))
print(string.index('c'))
'''==>
1
1
-1
ValueError: substring not found
'''
#split:
string='a b c d e'
s=string.split(' ') #按一个空格位分割,如果有两个字符之间有n+1个空格,在列表会有n个' '
print(s)
for str1 in s:
print(str1)
'''
['a','b','c','d','e']
a
b
c
d
e
'''
string='a b' #a、b之间有3个空格
s=string.split(' ')
for str2 in s:
print(str2)
'''
a
b
'''
s=string.split() #此时以空格分隔
#==>s=['a','b']
#replace:
string = 'hello_world'
s=string.replace('_',' ')
print(string)
print(s)
'''
'hello_world' 可以看成string生成一个副本,对其副本修改而原本未变
'hello world'
'''
#eval+input
a=input('请输入:') #123
#a='123'(str类型)
b=eval(input('请输入:'))
#b=123(int类型)
5.字符串的格式化输入
format:当指定了 s类型 ,只能传字符串值,如果传其他类型值不会自动转换
当你不指定类型时,任何类型都能成功,如无特殊必要(比如限制float的小数位),可以不用指定类型
f+string:可读性更强
#运用%:
num=1/3
name='苹果'
print('价格是%.2f块钱一斤' %num) #单个占位符
print('%s的价格是%.f块钱一斤' %(name,num)) #多个占位符
#format、{}:
name = '张三'
hight = 170.4
score = 95
print('Hello, {}, 身高是{:.1f}厘米,成绩为 {}'\ #自动配对,括号里可以不加东西(为增加可读性,可以加索引:0,1,2....
.format(name,hight,score))
print('Hello, {}, 身高是{:.1f}厘米,成绩为 {:d}'\
.format('李四',165.5,99)) #可以自己赋值
print('Hello, {name:}, 身高是{hight:.1f}厘米,成绩为 {score:d}'\
.format(name='李四',score=99,hight=165.5)) #可以用关键字,可读性更强,这时候可以不考虑顺序
#f+string
name = '张三'
hight = 170.4
score = 95
print(f'Hello, {name}, 身高是{hight}厘米,成绩为 {score}') #在字符串前面加f
(二)数字
1.运算:+,-,*, /,**(次方)
2**3=8
2.str():把数字型变/常量转变成字符串
a=10 #a默认为int型
str(a) #将a转成字符串型
(三)注释
#:单行注释
‘’'多行注释
(四)列表与元组
区别:列表可修改,元组不可修改
列表用[ ],元组用( )
1.访问列表/元组
count计数
index查找
(与(一)、4类似)
alphabet1=['a','b','c','d'] #创建列表alphabet1,单双引号都可以
print(alphabet1)
#==>['a','b','c','d'] #只会显示单引号
print(alphabet1[0]) #索引从0开始
#==>a #无方括号和引号
#count,index:
list1 = ['a','b','a','d','a','f']
print(list1.count('a'))
print(list1.index('a'))
#==>3
#==>0
alphabet2=('a','b','c','d') #创建元组alphabet2,其余同上
注:索引-1会访问列表最后一个值,-2是倒数第二个数(不用费心数几个元素)
[m:n]:访问部分列表(切片),m:start索引(包含);n:last索引(不包含)
[:n]:从起始到n;[m:]:从m到末尾(m为负数时表示访问最后几个元素)
list0=["B","a","b","A","1"," ","0"]
print(list9[0:2])
#==>['B','a']
#元组类似
2.添加删除元素(列表)
.append():在列表末尾添加元素
.insert():在列表中插入元素
del:删除元素
.pop():括号无值默认删除列表最后一个元素;加上数值可以任意删除,并返回删除的元素
.remove():删除特定值的元素(一次只能删一个)
len():求出列表长度
.extend():合并两个列表(被合并列表元素未被删除)
alphabet=["a","b","c","d"]
print(alphabet)
#==>['a','b','c','d']
#.append():
alphabet.append("e")
print(alphabet)
#==>['a','b','c','d','e']
#.insert():
alphabet.insert(5,"f")
print(alphabet)
#==>['a','b','c','d','e','f']
#del:
del alphabet[0]
print(alphabet)
#==>['b','c','d','e','f']
#.pop():
alphabet.pop(0)
#==>['c','d','e','f']
#==>b 此时第一个元素b已经被删除
print(alphabet)
#==>['c','d','e','f']
#.remove():
alphabet.remove("c")
print(alphabet)
#==>['d','e','f'] 注意一次只能删一个
#.extend():
list1=[1,2,3]
list2=[4,5]
list1.extend(list2)
print(list1)
print(list2)
'''
[1,2,3,4,5]
[4,5]
'''
3.组织列表
.sort():对列表进行永久排序(按首字符正序排序,顺序:空格>012>ABC>abc,反序要在括号里加 reverse=True “T”要大写)
sorted():对列表进行临时排序,同上
.reverse():永久反转列表顺序(不是按首字符排序,只是反转)
sort0=["B","a","b","A","1"," ","0"]
sort0.sort()
print(sort0)
#==>[' ','0','1','A','B','a','b']
sorted0=["B","a","b","A","1"," ","0"]
print(sorted(sorted0))
#==>[' ','0','1','A','B','a','b']
print(sorted0)
#==>["B","a","b","A","1"," ","0"]
reverse0=["B","a","b","A","1"," ","0"]
reverse0.reverse()
print(reverse0)
#==>['0',' ','1','A','b','a','B']
print(reverse0[0:2])
#==>['B','a']
4.复制列表
- a1=a
- a1和a为同一列表 a2=a[:]
- a2是a的副本,两个独立
a=[1,2,3]
a1=a #a1和a是同一个列表,修改a,a1也会变化
a2=a[:] #a2和a内容相同,但不是同一个列表
a.append(4)
print(a1)
#==>[1,2,3,4]
print(a2)
#==>[1,2,3]
5.修改列表
magicians=['张三','李四','王五']
#打印人名
def print_name(magicians):
for magician in magicians:
print(magician)
#修改人名(1)
def add_name(magicians):
for magician in magicians:
magician=magicians.pop(0)+"nb"
magicians.append(magician)
return magicians
#修改人名(2)
def add_name(magicians):
magicians=[f'{magician}nb' for magician in magicians]
return magicians
print("修改前")
print_name(magicians)
#执行修改函数:
magicians=add_name(magicians)
print("\n修改后\n")
print_name(magicians)
#==>magicians=['张三nb','李四nb','王五nb']
6.列表生成式
利用for遍历,if判断
#数字型
list0=[1,2,3,4,5]
#创建新列表为list1,各元素为list0的100倍,即list1=[100,200,300,400,500]
list1=[n*100 for n in list0]
print(list1) #注意list0没有被修改
#字符串型
快速创建列表list2,为['app_0','app_1','app_2','app_3','app_4','app_5','app_6','app_7','app_8','app_9']
list2=[f'app_{n}' for n in range(10)] #或者
list2=['app_%d'%n for n in range(10)]
#增加条件
#创建新列表为list3,元素为1~100内的奇数
list0=list(range(100)) #list0包含0~99
list0=[n+1 for n in list0] #修改为1~100
list3=[n for n in list0 if n%2!=0]
#创建list0,元素为list1~3的交集
list1 = [1,3,6,7,12,32,65,]
list2 = [2,3,5,6,12]
list3=[1,3,12,15]
list0=[n for n in list1 if n in list2 and n in list3]
#创建list0,包含'xyz'和'abc'的全排列
list0=[m+n for m in 'xyz' for n in 'abc']
6.生成器
- 原因:
- 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
关键字:next、yield
#例子:从1到10
#常规列表
l=[n+1 for n in range(10)]
#打印
print(l)
#生成器
g=(n+1 for n in range(10))
#打印法1
print(next(g)) #打印1
print(next(g)) #打印2
#打印法2
for i in g:
print(i)
#函数:得到小于max_num的质数
def factor(max_num):
# 建立一个列表,存储质数
factor_list = []
n = 2
while n<max_num:
find = False
for f in factor_list:
# 先看看列表里面有没有能整除它的
if n % f == 0:
find = True
break
if not find:
factor_list.append(n)
yield n #yield类似return,但是没有终止函数
n+=1
#调用函数
g=factor(10)
for i in g:
print(i)
7.元组不可修改元素,但可以给元组变量重赋值
a=(1,2,3,0)
print(a)
#==>(1,2,3,0)
a=(1,2,3)
print(a)
#==>(1,2,3)
#这样元组就被修改了
(五)for循环
- 语法:
- for ××(临时变量名)in ××(列表名): (冒号)
- 循环语句(要Tab缩进)
range(x,y,z):x:start值(包含);y:last值(不包含);z:step步长
注:不加步长时,默认x<y
list():创建数字列表
tuple():创建数字元组
min():最小值函数
max():最大值函数
sum():求值函数
alphabets=['a','b','c','d']
for alphabet in alphabets:
print(alphabet)
print("That's all.")
'''===>
a
b
c
d
That's all.
'''
for a in range(1,4):
print(a)
'''===>
1
2
3
'''
num1=list(range(1,7,2))
print(num1)
#==>
#[1,3,5]
num2=tuple(range(1,7,2))
print(num2)
#==>
#(1,3,5)
#创建平方列表
#方法一:
squares1=[] #创建空列表
for i in range(1,5):
squares1.append(i**2) #将range中的每个值平方,附加到squares的末尾
print(squares1)
#方法二
squares2=[i**2 for i in range(1,5)]
print(squares2)
#==>
#[1,4,9,16]
(六)if判断
- 语法
- for 条件 : (冒号)
执行语句(缩进)
elif 条件:
执行语句
…
else:
执行语句
逻辑运算符:==,>,<,>=,<=,!=
and ,or,in,not in
字符串:非空字符为true,空字符“’’”为false
a=list(range(1,5))
if 2 in a:
print("yes")
else:
print("no")
#==>yes
(七)字典
1.创建、访问字典
#创建字典
#方法一
match={'a':1,'b':2,'c':3} #花括号,键-值中间用冒号,各个键-值对用逗号隔开
#方法二
match={} #创建空字典
match['a']=1 添加各个键-对
match['b']=2
match['c']=3
print(match['a']) #访问:中括号
print(match['b'])
print(match['c'])
'''==>
1
2
3
'''
2.添加、删除键-值对
match={'a':1,'b':2,'c':3}
match['d']=4
print(match)
#==>{'a':1,'b':2,'c':3,'d':4}
#Python只关心键-对配对关系,不关心添加顺序
del match['a']
print(match)
#==>{'b':2,'c':3,'d':4}
3.遍历字典
.items():遍历字典所有键-值对
.keys():遍历字典所有键
sorted():按(键)顺序遍历
.values():遍历字典所有值
set():剔除重复项(好像也进行了排序)
#遍历字典所有键-值对
match1={'a':1,'b':2,'c':3}
for k,v in match1.items():
print("k: "+k)
print("v: "+v)
'''
k: a
v: 1
k: b
v: 2
k: c
v: 3
'''
#遍历字典所有键
match2={'d':4,'a':1,'c':3,'b':2}
for k in match2.keys():
print("k= "+k)
'''
d
a
c
b
'''
#按顺序遍历字典所有键-对
match3={'d':1,'a':4,'c':2,'b':3}
for k,v in sorted(match1.items()):
print("k: "+k)
print("v: "+str(v))
'''
k: a
v: 4
k: b
v: 3
k: c
v: 2
k: d
v: 1
'''
#剔除重复值,遍历字典中的值
match4={'a':1,'b':2,'c':1}
for v in set(match4.values())
print("v: "+str(v))
'''
v: 1
v: 2
4.嵌套
字典嵌套列表,列表嵌套字典,字典嵌套字典
(八)用户输入和while循环
1.输入函数
input():输入字符串
int():将字符串型转化为int型
float():将字符串型转化为float型
2.while循环
语法:while 循环条件:(冒号)
循环执行语句(缩进)
break:退出循环
continue:跳出本次循环
#在列表之间移动元素
c=[]
a=[1,2,4,5]
while a:
b=a.pop() #b读取a末尾元素
c.append(b)
c.sort() #移动之后a和c的元素顺序正好相反
print(c)
#删除列表中特定值的所有元素
a=[1,1,2,1,3]
while 1 in a:
a.remove(1)
print(a)
#==>[2,3]
(九)函数
1.基础
- 语法: def 函数名(形参): (冒号)
- 函数内容 函数名(实参) (调用)
- 位置实参:实参与形参顺序一一对应,数量一一对应
关键字实参:数量一一对应
默认值形参:先列出没有默认值的形参
def match(alphabet,number):
print(alphabet+"\t"+number)
#调用:
#位置实参:
match('a',"1") #注意次序,一一对应
#==>a 1
#关键字实参:
match(number='1',alphabet='a') #此时可以不用考虑顺序
#==>a 1
#默认值形参:
def match(alphabet,number='1'): #直接规定number为1,调用时可不输入number的值
print(alphabet+"\t"+number)
#注意:使用默认值时,在形参列表中必须先列出没有默认值的形参
2.返回
return:返回(数值,列表,字典都可以),可返回多个,将它们打包成一个元组
#返回数值
def add(a,b):
return a+b
print(add(2,4))
#==>6
#返回字典
def get_name(first,last):
dic={'姓':first,'名':last}
return dic
name=get_name('成','超华')
print(name)
3.其他
#1.传递列表
first=['1','2','3','4']
last=[]
def convey(first_1,last_1):
while first_1:
temp=first_1.pop(0)
last_1.append(temp)
convey(first,last)
#转移列表后
print(first)
print(last)
'''==>
first:[]
last:['1','2','3','4']
'''
'''注意:这样转移对列表做的是永久性修改
为保留原件,可使用副本[:]
first_1=first[:] #创建first的副本
convey(first_1,last)#first的副本会变化而first不变
'''
#2.传递任意数量的实参
# *形参
#星号的作用:创建空元组,将收到的所有值都存在该元组
def fun(*list0):
for list00 in list0:
print(list00)
list1=[1] #此时list0=([1],)
list2=[1,2,3,4,5] #此时list0=([1,2,3,4,5],)
fun(list1)
fun(list2)
fun('1','2','3') #此时list0=('1','2','3')
'''==>
[1]
[1,2,3,4,5]
1
2
3
#注意到前两个传递的是一个列表,所以打印出来的是列表
最后一个是三个字符
'''
#传递任意数量的关键字实参
# **形参
#双星号:创建空字典
def build_profile(name,**informations): #函数:包含姓名以及其他未知信息
profile={} #先创个空字典接受键-值对
profile['name'.title()]=name
for k,v in informations.items():
profile[k.title()]=v
return profile
people_profile = build_profile('张三',location='山东',phone='110') #未知信息为地址location和电话phone
print(people_profile)
#==>{'name':'张三','location':'山东','phone':'110'}
4.模块、多文件编程
- 导入模块语法
- 导入整个模块:import 模块名
- 调用函数:模块名 . 函数名()
导入特定函数:from 模块名 import 函数名1,函数名2…
导入模块中所有函数:from 模块名 import * (导入的函数可能会冲突,慎用)
as关键字:
给导入的函数起别名:from 模块名 函数名 as 函数别名
(原因:函数名称冲突;函数名称太长)
给模块起别名:import 模块名 as 模块别名
#文件一:fun.py
def add(a,b):
print(a+b)
def mult(a,b):
print(a*b)
#文件二:main1.py 注意:要设置启动文件
import fun #导入fun.py模块
fun.add(1,3) #调用fun.py中的add函数
#文件三:main2.py
from fun import mult #只调用mult函数
mult(2,3) #此时不用加fun.
#文件三:main2.py
from fun import *
#给函数起别名(文件三)
from fun mult as mu #将mult函数起别名为mu
mu(2,3)
#给模块起别名(文件三)
import fun as f
5.作用域与global变量
局部变量 作用域:在函数内
全局变量 作用域:在函数外
函数优先使用局部变量 在没有局部变量的情况下, 使用全局变量
name='James'
def print_name():
name='John'
print(name)
print_name()
print(name)
'''
John
James
没有改变全局变量name
'''
#global变量:
name='James'
def print_name():
global name #name用的是全局变量
name='James'
print(name)
print_name()
print(name)
'''
James
James
'''
6.lambda匿名函数
- 格式:
- lambda 参数1,参数2… : 返回值
注:lambda 只是一个表达式,函数体比 def 简单很多。
lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
#1.
add=lambda a,b:a+b
sum=add(2,5)
print(sum)
#==>7
#2.直接赋值
b=(lambda a,b:a**b)(2,10)
print(b)
#==>1024
7.高阶函数
一个函数可以接收另一个函数作为参数,这种函数称为高阶函数
- 简单运用
add=lambda a,b:a+b
mul=lambda a,b:a*b
ss=lambda a,b:a**b
def fun_ab(a,b,f):
return f(a,b) #参数包括另外函数
print(fun_ab(2,10,add))
print(fun_ab(2,10,mul))
print(fun_ab(2,10,ss))
'''
12
20
1024
'''
- map关键字
map()函数接收两个参数,一个是函数,一个是sequence/Iterator(序列)
map将传入的函数依次作用到序列的每个元素,并把结果作为新的序列返回
square=lambda a:a*a
list0=list(range(1,10))
#将list0的各个元素分别代入square函数,得到result
result=map(square,list0)
list1=list(result)
print(list1)
#==>[1, 4, 9, 16, 25, 36, 49, 64,81]
- reduce关键字
reduce()有两个参数,一个是函数(有两个参数),一个是序列
先对序列中的第 1、2 个元素代入函数,得到的结果再与第3个元素代入函数
依此类推,最后返回一个结果
注:reduce函数要导入functools 模块
from functools import reduce
factorial=lambda a,b:a*b
list0=[1,2,3,4]
result=reduce(factorial,list0)
print(result)
#==>24
- sorted排序
#通过key制定函数进行排序
sorted([36, 5, -12, 9, -21], key=abs)#abs;绝对值函数
#另一方法:map
sorted(map(abs,[36, 5, -12, 9, -21]))
#按坐标到原点距离大小排序
用元组储存各点的坐标
points = [(5,2), (7,3), (3,4),(1,1),(2,6)]
dis=lambda p:p[0]**2+p[1]**2
sorted(points,key=dis)
#==>[(1, 1), (3, 4), (5, 2), (2, 6), (7, 3)]
(十)类
1.基础
语法:class 类名(): (类名首字母大写)
注:1. 类名采用驼峰命名法,即将类名中的每一个单词首字母大写,不用下划线。实例名和模块名小写,并在单词之间加下划线
2. 空行:在类中用一个空行分隔方法;在模块中用两个空行分隔类
#以Athlete类为例
class Athlete: #类名首字母大写
def __init__(self,a_name,a_dob=None,a_times=[]):
#初始化描述Athlete的属性
self.name = a_name
self.dob = a_dob
self.times = a_times
#得到不重复的前三位数
def top3(self):
return sorted(set([self.sanitize(t) for t in self.times]))[0:3]
def sanitize(self,time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return (time_string)
(mins,secs) = time_string.split(splitter)
return (mins+'.'+secs)
第一部分:class定义类的关键字,Athlete符合python标识符命名规则,:表示类内容的开始
def init(self,a_name,a_dob=None,a_times=[]):第二部分:def定义函数的关键字,init 方法是一个特殊方法会在实例化对象时自动调用,我们会在这个方法中对数据进行赋值。self作为类中函数的第一个参数,方便该方法调用该类的其他属性和方法。
第三部分:自定义的属性和方法
2.继承
继承:一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类/超类superclass,新类称为子类。子类继承父类的所有属性和方法,同时也可以定义自己的属性和方法
- 定义属性:在调用父类后,再以self.属性=参数写上即可
- 定义方法:
重写父类方法----定义一个和父类方法相同的方法。
特有方法----和普通方法写法相同
#定义橄榄球运送员类,继承Athlete类,并添加a_squat属性
class Rugby(Athlete): #在括号内加父类名
#子类的属性
def __init__(self,a_name,a_bod,a_squat,a_times):
#调用父类__init__
Athlete.__init__(self,a_name,a_bod,a_times)
#或者:super.__init__(self,a_name,a_bod,a_times)
self.squat = a_squat
#修改top3函数,要求可以重复,并得到后三位数
def top3(self):
return sorted([self.sanitize(t) for t in self.times])[-3:]
3.将实例做属性
原因:当使用代码模拟实物时,类的细节也会越来越多,属性和方法清单以及文件会越来越长。这时,可以将类的一部分作为一个独立的类提取出来。即:将大型类拆分成多个协同工作的小类
#将squat作为独立的类
class Squat():
def __init__(self,a_squat=0):
self.squat=a_squat
def print_squat(self):
print(f'最多深蹲{self.squat}次')
#定义Rugby类
class Rugby(Athlete):
def __init__(self,a_name,a_dob,a_squat,a_times=[]):
Athlete.__init__(self,a_name,a_dob=None,a_times=[])
self.squat=Squat(a_squat)
#创建实例zhangsan
info='张三,2006-11-11,70,2-34,3:21,2.34,2.45,3.01,2:01,2:01,3:10,2-22'.strip().split(',')
z_name=info.pop(0)
z_dob=info.pop(0)
z_squat=info.pop(0)
z_times=info
zhangsan=Rugby(z_name,z_dob,z_squat,z_times)
#调用Squat类的属性
zhangsan.squat.squat=80
#调用Squat类的方法
zhangsan.squat.print_squat()
4.导入类
- 语法:
- 导入特定类:
- from 模块名 import 类1名,类2名,……
- 导入所有类:
- import 模块名( 调用:模块名.类名)
from 模块名 import * (不推荐)
- import 模块名( 调用:模块名.类名)
(十一) 文件和异常
1.打开文件
- 语法:
with open ('文件路径','模式实参') as f(别名,任意):(文件路径用“/”) 1.contents=f.read() (读取文件内容。内容以**字符串**形式存储到contents中) 2.for line in f (逐行读取) 3.lines=f.readlines() (读取文件每一行,存储在一个列表中)
'''artical.txt文件内容:
2-34,3:21,2,34,2.45,3.01,2:01,2:01,3:10,2-22
2:58,2.58,2:39,2-25,2:55,2:54,2.18,2:55,2:55
2.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-21
'''
#打开文件
with open('artical.txt') as f:
#1.
contents=f.read()
print(contents)
#2.
for line in f:
print(line)
'''
2-34,3:21,2,34,2.45,3.01,2:01,2:01,3:10,2-22
2:58,2.58,2:39,2-25,2:55,2:54,2.18,2:55,2:55
2.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-21
'''
#3.
lines=f.readlines()
print(lines)
'''
['2-34,3:21,2,34,2.45,3.01,2:01,2:01,3:10,2-22\n', '2:58,2.58,2:39,2-25,2:55,2:54,2.18,2:55,2:55\n', '2.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-21\n', '2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38']
'''
2.写入、附加到文件
模式参数:’r’:读取模式,‘w’:写入模式,’a’:附加模式
注:1.‘w’模式下,如果指定文件存在,python在返回对象前清空该文件,不存在则会创建一个
2.写入内容末尾不会自动加上换行符。可以手动添加“\n”
3.’a’模式下,不会覆盖原文件,会将写入内容添加到文件末尾;文件不存在会创建一个
#‘w’模式
#将2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38写入artical.txt
with open ('artical.txt','w') as f:
f.write('2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38')
'''
2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38
先前的内容会清空
'''
#‘a’模式
#将2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38添加到artical.txt
with open ('artical.txt','a') as f:
f.write('\n2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38')
'''
2-34,3:21,2,34,2.45,3.01,2:01,2:01,3:10,2-22
2:58,2.58,2:39,2-25,2:55,2:54,2.18,2:55,2:55
2.59,2.11,2:11,2:23,3-10,2-23,3:10,3.21,3-21
2:22,3.01,3:01,3.02,3:02,3.02,3:22,2.49,2:38
'''
3.异常
try:
<语句> #运行本该运行的代码
except <名字>:
<语句> #如果在try部份引发<名字>异常,则执行的代码。啥也不做可以用pass
except <名字>,<数据>:
<语句> #如果引发了’名字’异常,获得附加的数据
else:
<语句> #没有异常发生会进行,发生异常不会进行
finally:
<语句> #有没有异常都会执行
一些异常名字:
ZeroDivisionError:用0当除数
IOError:输入输出错误
TypeError:类型错误
#对list0中的每一个数字都进行加1操作。如果异常则报出异常类型和循环次数
list0 = [1,2,'3',4,]
for i in range(len(list0)):
try:
list0[i]+=1
print(list0)
except IOError as i:
print(i)
print('输入输出异常')
except TypeError as t:
print(t)
print('类型错误')
else:
print('正确执行')
finally:
print(f'第{i+1}次循环')
'''
[2, 2, '3', 4]
正确执行
第1次循环
[2, 3, '3', 4]
正确执行
第2次循环
can only concatenate str (not "int") to str
类型错误
第3次循环
[2, 3, '3', 5]
正确执行
第4次循环
'''
4.存储数据
模块json:能将简单的python数据结构转储到文件中,并在程序再次运行时加载该文件的数据 (要导入json)
json.dump(存储数据,文件):存储
json.load (文件):读取
#简单操作:存储一个数字列表
import json
numbers=[1,2,3,4,5]
#存储
with open ('numbers.json','w') as f:
json.dump(numbers,f)
#读取
with open ('numbers.json') as f:
num=json.load(f)
print(num)
#保存用户姓名
filename='username.json'
try:
with open(filename) as f:
username=json.load(f)
except FileNotFoundError:
username=input('What\'s your name?')
with open(filename,'w') as f:
json.dump(username,f)
print('hello,'+username)
else:
print('welcome back,'+username)
(十二)测试代码
1.基础
模块:unittest
单元测试:用于核实函数的某个方面没有问题
测试用例:是一组单元测试,这些单元测试一起核实函数在各个情境下的行为都符合要求
全覆盖式测试:包含一整套的单元测试,涵盖各种可能的函数使用方式
unittest模块的断言方法
| 方法 | 用途 |
|---|---|
| asserEqual(a,b) | 核实a==b |
| asserNotEqual(a,b) | 核实a!=b |
| asserTure(x) | 核实x为ture |
| asserFalse(x) | 核实x为false |
| asserIn(item,list) | 核实item在list中 |
| asserNotIn(item,list) | 核实item不在list中 |
2.测试函数
#函数:可以返回first last 形式的名字,也可以返回first middle last 形式
def getname(first,last,middle=''):
if middle:
fullname=first+' '+middle+' '+last
else:
fullname=first+' '+last
return fullname.title()
#测试:测试 Zhang San 和 Zhang Xiao San 两种形式能否成功运行
import unittest
class NameTestCase(unittest.TestCase):
#测试 Zhang San (测试方法开头为test
def test_first_last(self):
fullname=getname('zhang','san')
#判断fullname是不是和Zhang San一样
self.assertEqual(fullname,'Zhang San')
#测试 Zhang Xiao San
def test_first_middle_last(self):
fullname=getname('zhang','san','xiao')
self.assertEqual(fullname,'Zhang Xiao San')
#运行测试
unittest.main()
'''
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
'''
3.测试类
#定义一个Questionnaire类以存储问卷问题和回答
class Questionnaire():
def __init__(self,question):
self.question=question
#创建一个空列表存储回答
self.responses=[]
#打印问卷问题
def show_question(self):
print(self.question)
#存储问卷回答
def store_response(self,response):
self.responses.append(response)
#打印问卷回答
def show_result(self):
print('问卷回答如下:')
for i in self.responses:
print(i)
#测试 单个回答(2)、三个回答(2,3,5)是否都能存储
import unittest
class QuestionnaireTest(unittest.TestCase):
#测试单个回答
def test_single_response(self):
question='说出任意数量的质数(0~10以内)'
questionnaire=Questionnaire(question)
questionnaire.store_response(2)
self.assertIn(2,questionnaire.responses)
#测试三个回答
def test_three_response(self):
question='说出任意数量的质数(0~10以内)'
questionnaire=Questionnaire(question)
new_responses=[2,3,5]
for response in new_responses:
questionnaire.store_response(response)
for response in new_responses:
self.assertIn(response,questionnaire.responses)
unittest.main()
4.setUp()方法
在测试类时,两个test中都创建一次对象
使用setUp()方法,则只需要创建对象一次,并在每个测试方法中使用
#上面可以修改为:
import unittest
class QuestionnaireTest(unittest.TestCase):
def setUp(self):
question='说出任意数量的质数(0~10以内)'
#区别,在实例前面加上self(即存储在属性中,可在这个类的任意部分使用
self.questionnaire=Questionnaire(question)
self.responses=[2,3,5]
#测试单个回答
def test_single_response(self):
self.questionnaire.store_response(self.responses[0])
self.assertIn(self.responses[0],self.questionnaire.responses)
#测试三个回答
def test_three_response(self):
for response in self.responses:
self.questionnaire.store_response(response)
for response in self.responses:
self.assertIn(response,self.questionnaire.responses)
unittest.main()
5.测试运行结果
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
以此为例:
每完成一个单元测试都会打印一个字符
- 正确:.(句点)
- 错误:E
- 测试导致断言失败:F
通过结果可以得知多少个测试通过了