初识函数--文件的读取和打开,已一节课一节课分开,可不看

#20200927  函数  第九节课
# 函数的概念:将一段程序封装起来,当需要使用时进行调用
#def 函数名(形参): 注意:1、参数个数随意,2、后面跟冒号1
# def sumdata(a,b): #这是形式参数,简称形参
# print(a+b) #函数内部语句,必须缩进
#sumdata(6,6) #这是实际参数,简称实参
#这个函数是最基础的,因为没有返回值
#print(sumdata(6,5)) #这里打印函数的返回值,返回的是none,表示没有返回值。怎样才能有返回值呢?
# def sumdata(a,b):
# print(a+b) #因为这个print语句在函数里面,所以执行函数的时候会把它打印出来,但是这个不是返回值
# return a+b #这个才是返回值。函数的返回值用return表示。一个函数如果没有返回值,或者return后面没有数据,函数的返回值就是None
# print(sumdata(6,6)) #这里有返回值了 ,返回的12
#思考图:函数中可以有多个return吗?
#可以!!!分支语句!!!eg:写一个函数可以返回某数的绝对值
# def jueduizhi(number):
# if number>=0:
# return number
# else:
# return -number
# print(jueduizhi(-5)) #有了返回值得打印出来才能看到
#在同一个分支里可以有多个return吗? 可以!!!elif!!! 但是只有第一个语句可以执行,后面的叫不可达语句
# def sumdate(a,b):
# return a+b
# return a*b #可以有多个return,但是不会被执行
# print('lalal') #不只是return不会被执行,所有语句都不会被执行
# print(sumdate(1,2))

#思考:return可以有多个值吗??可以的!多个值会已元组房形式出现
# def sumdate(a,b):
# return a+b,a*b,a**6
#这里如果是return [a+b,a*b,a**6] ,返回的就是一个列表,为什么?因为这个对于return来说就只是一个值,一个列表也只是一个值
#这里如果是return (a+b,a*b,a**6),可以理解为也是一个值,这个值是元组,有多个元素的元组
# q=sumdate(2,3) #可以给函数自定义命名
# print(q) #打印的时候打印名字就行了
# print(sumdate(2,3)) #查看类型可以用type()函数print(type(sumdate(2,3)))

#参数的默认值/缺省值
# def sumdate(a=6,b=9):
# return a+b
# print(sumdate()) #这里因为在定义函数的时候就设置了缺省值,所以打印的时候没有传实参,也可以有结果15,
# print(sumdate(2,6)) #也可以直接传参,这样就用的是当前传的参数
# print(sumdate(a=2,b=6))
# print(sumdate(2,b=6))
#print(sumdate(a=2,6)) #以上写法都者却,只有前全后不全写会报错
#对于普通的参数而言(当没有缺省值时),形参和实参的数量得一致,不能多也不能少。当有缺省值时,可以少传,但是不能多传

#可变长度参数*args
# def fu(a,*args): #定义一个函数,两个参数,第二个参数是可变长度参数
# #return a,args #这样子会多一层元组
# return a,*args #这样子不会多一层元组,都是平级的
# #print(fu(12)) #当只传一个值时,打印结果是:(12, ()),后面多了一个元组
# print(fu(12,11,10)) #当传值大于等于2个时,会把第一个之后的只都放到元组里面去
#按住Ctrl键点击函数名可以查看内置函数缺省值,比如:def print(self, *args, sep=' ', end=' ', file=None):
# print(10,20,30,sep='a') #sep缺省值是空格,传参a,结果是10a20a30
# print(10,20,30,end='eee') #10 20 30eee5 6 7
# print(5,6,7)

#关键字参数 **kwargs
# def fun2(a,*args,**kwargs): #书写顺序,必须是普通参数>可变长度参数>关键字参数
# return a,kwargs
# print(fun2(100,aa=99123456.
# ,bb=98,cc=97))



#20200927   第十节课  
#对象的方法,方法其实就是一种函数,只是方法是放在类当中的
# str1='fasdg' #str.出来的那些就是方法
# #方法一:str.isdigit() #判断某个字符串是否是由纯数字组成 注意是字符串 eg:
# str2=123123123
# str3='-1' #注意这个判断是否是纯数字也是False,因为符号不识别
# #print(str1.isdigit()) #打印结果得False
# # print(str2.isdigit()) #打印会报错,因为str2不是字符串
# 方法二:isalpha() #判断某个字符串是否是纯字母
# print(str1.isalpha()) #True
#方法三:strip() #去掉字符串前后的特定字符,缺省值是去掉空格 eg:
# stra=' f f f fe e '
# print(stra.strip()) #只去掉字符串前后的空格
# strs='!!njew jiew gbs!!!'
# print(strs.strip('!')) #也可以去掉字符串前后的任意字符,只要把缺省值空格改成要去掉的东西就好了
# 思考:怎么去掉一个字符串的全部相同的某个东西?用replace() eg:
# staaa='***f*r**e*e**g*h*j*'
# print(id(staaa))
# print(id(staaa.replace('**',''))) #不是只替换一个,而是全部你都替换
#打印得:*f*re*eg*h*j*,把要去掉的东西改成,替换成 replace('旧值',‘新值’)
# staaa='*$$*&&*f*r**e*e**g*h*j*'
# print(staaa.replace('*',' ').replace('$','1').replace('&','2'))
#还可以多个replace一起用,因为replace返回的是字符串,而字符串就可以用replace方法
# startswith,判断是否以某些字符开头,endswith,判断是否以某些字符结束
# 思考题:判断用户输入的某个身份证是否是重庆的身份证,如果是就打印是的,不是就打印不是的
# sfz=input('请输入你的身份证:')
# if len(str(sfz!=18)):
# print ("请输入您的18位身份证号码")
# else:
# print('是')
# if sfz[:16].isdigit():
# print ("请输入纯数字")
# else:
# print('是的')
# if sfz.startswith('5'):
# print('重庆人')
# else:
# print('不是的') #瞎想的程序,不成熟,有空再完善
#思考题:判断某个身份证是否是重庆的身份证,如果是就打印是的,不是就打印不是的
# sfz='500388199906066666'
# if sfz.startswith('5'):
# print('是的')
# else:
# print('不是的')
#判断一个身份证的主人的性别,身份证倒数第二位是基数则为男,偶数即为女

#:方法:split(参数),以参数为分隔符对字符串进行切割,切割之后的返回值是一个列表,切割符不会消失。eg:
# sta='hdhudijdgkodhg'
# #print(sta.split('d')) #得:['h', 'hu', 'ij', 'gko', 'hg'],返回的是列表
# # print(sta.split('g')) #得:['hdhudijd', 'kodh', ''],如果是以首未字符作为切割符进行切割,则会出现空字符
# print(sta.split('h')) #得:['', 'd', 'udijdgkod', 'g']

#join()方法,拼接字符串
查='aaa'
#print(查.join('fffff')) #得到faaafaaafaaafaaaf 是把查看成一个整体插入了fffff中间
print(查.join(['e','r','t'])) #得:eaaaraaat

# 20200928  格式化字符串
#第十一节课
# 有个例子:
# a = 3
# b = 5
# print(str(a)+'+'+str(b)+'='+str(a+b))#但是这样写太麻烦了
# 格式化字符串 方案一
# print('%s+%s=%s' % (a, b, a + b))
# 因为是字符串所以用的%s,如果是数字用%d。%f表示浮点类型
# info='我叫%s,他叫%s,我今年%s岁'%('a','b',12) #百分号前后的参数需一致
#info='我叫%6s,他叫%6s,我今年%6s岁'%('a','b',12)
#可以在%后面添加数字n,表示至少有n位数,不足时用空格补齐,超过n位时显示完整的参数如下
# info='我叫%3s,他叫%3s,我今年%3s岁'%('啦啦彭于晏','b',12)
#print(info)
# info='我叫%s,他叫%s,我今年%05d岁'%('a','b',12)
# #对于数字(%d)而言,可以补0,写成%0nd,n是任意自然数,不足n位用0补齐,超过则显示完整
# print(info)
#在这个字符串格式化方案中,所有的字符都是右对齐,如果需要左对齐,添加一个符号。如:
# info='我叫%-5s,他叫%-5s,我今年%0-5d岁'%('a','b',12)
# print(info)
#%f 浮点型,%m.nf m表示最少显示多少位,不足用空格补齐 n表示保留多少位小数 eg:
# num='%6.6f'%(3.1) #显示的是3.100000
#num='%6.6f'%(3.1415926) #显示的是3.141593(这里是五舍六入)
# num='%6.2f'%(3.1) #显示的 3.10,不足用空格补齐
# # num='%06.2f'%(3.1) #得003.10,表示最少显示6位,不足用0补齐,保留两位小数
# print(num)

#方案二
# s='我的名字是{},他的名字是{},年龄是{}'.format('aa','bb',66)
# print(s)
#补齐方法 {:n} n表示最少显示n位 超过全部显示
# s='我的名字是{:6},他的名字是{:3},年龄是{:6}'.format('aabbccdd','bb',66)
# print(s) #在这个方案中,字符串默认左对齐,数字默认右对齐。
# s='我的名字是{:6},他的名字是{:3},年龄是{:06}'.format('aa','bb',66)
# print(s) #数字可以{:0n},表示最少显示n位,不足在数字左边用0补齐
# s='我的名字是{:>6},他的名字是{:^6},年龄是{:^06}'.format('aa','bb',66)
# print(s) #>号表示右对齐,<号表示左对齐。默认是左对齐。^表示居中对齐
#此处得:我的名字是 aa,他的名字是 bb ,年龄是006600
#在这个方案中是可以随意补0 但是字符串补0必须得加上大于或者小于号
# s='我的名字是{:>06},他的名字是{:<06},年龄是{:^06}'.format('aa','bb',66,67)#这是一个元组
# print(s) #我的名字是0000aa,他的名字是bb0000,年龄是006600
# #前后参数对比,前面的参数比后面的多,会报错,后面的参数比前面的对,不会报错
#下标取值法:直接在{}的冒号前面输入元组中的下标达到改变值的方法
# s='我的名字是{1:*>6},他的名字是{0:<06},年龄是{3:^06}'.format('aa','bb',66,67)#这是一个元组
# print(s)
#如果本来就想显示{},用{{}},但是如果{}里面同时向显示参数怎么办?再加一层、
# s='我的名字是{{:>06}},他的名字是{:<06},年龄是{:^06}'.format('aa','bb',66,67)#这是一个元组
# print(s) #得我的名字是{:>06},他的名字是aa0000,年龄是00bb00,没有显示出{}里面的参数
# s='我的名字是{{{:>06}}},他的名字是{:<06},年龄是{:^06}'.format('aa','bb',66,67)#这是一个元组
# print(s) #得我的名字是{0000aa},他的名字是bb0000,年龄是006600。完成了预期想法

#在方案二中有一种更简便的写法,但是必须是python3.6以上才可以使用
# name1='aoe'
# name2='ywu'
# print(f'我的是{{{name1}}},你的是{name2}') #正常写法
# print(f'我的是{{{name1:>6}}},你的是{name2:^9}')
#得我的是{ aoe},你的是 ywu ,一样可以用方案2的补齐方法

#全局变量 局部变量
a=3 #全局变量,任何地方的代码都可以用.顶格写
def fun1(): #定义一个函数
global b #声明一个全局变量,即让函数内的变量全局内可用。如果是globle的全局变量a,那a会被重新赋值
b=6 #局部变量,只能在函数内使用
return b #必须有返回一下
fun1() #在函数外调用该函数,就可以让b被赋值的语句执行一次
print(a,b) #打印结果是:6



#20200928_循环语句与注释   第十二节课
#while循环
# i=0
# while i <=100: #当while后面的表达式为真时,则执行while循环,直到表达式未假时,停止循环
# print(i,end=' ') #修改结尾处缺省值未换行的,把结尾改成空格,让打印出来的数能在同一行,好看些
# i+=10 #i不会自己涨,所以要自增长,实现循环,确保不陷入死循环

#怎么实现十个十个数排成一排?
# i=0
# while i <=100:
# if i%10==0: #1除以10的余数等于0
# print(i)
# else:
# print(i,end=' ')
# i+=1
#for循环 如果有明确的循环次数没建议使用for循环,如果没有明确的循环次数,就适应while循环,不过两者可以互相替换
# for i in range(1,11): #包含起始值,不包含终止值,起始值为0时可以省略,步长不写就默认为1
# print(i)

#两种不同的for循环遍历某个列表
#第一种方法:用range函数循环取值
# list1=['我','和','我','的','祖国']
# for i in range(0,len(list1)): #第一种写法,这里的0可以省略
# print(list1[i])
#第二章方法:遍历
# list1=['我','和','我','的','祖国']
# for one in list1:
# print(one,end=' ')

#break和continue的用法,break是终止循环,continue是跳出当次循环。如:
# for i in range(1,11):
# if i==5:
#break #如果是break,打印结果是1 2 3 4,后面不继续循环了
#continue #如果是continue,打印结果是1 2 3 4 6 7 8 9 10,只是结束i等于5的那次循环,后面还会继续循环的
#pass #占位符,不跳出循环,如果后面有语句正常执行
#print('you are so beautiful'),如果上面只有pass,会继续打印这句话
# print(i)
#循环本身也可以带一个else,当循环成功运行完成之后,会执行一次else中的语句
# else:
# print('循环执行完毕')

#用print函数,配合循环语句写一个倒计时 倒计时100秒
# for i in range(10,0,-1): #range(起始值,终止值,步长),因为是倒计时,所以起始值大于终止值
# print(f'倒计时{i}秒') #f'是格式化字符串,不懂课后理解
#进阶版写法:
# import time
# for i in range(10,0,-1): #range(起始值,终止值,步长),因为是倒计时,所以起始值大于终止值
# print(f'倒计时{i}秒')
# time.sleep(1)
#如果只想让秒数变化怎么办?
import time
for i in range(3,0,-1): #range(起始值,终止值,步长),因为是倒计时,所以起始值大于终止值
print(' ',f'倒计时{i}秒',end=' ') #' '表示让打印的光标刷新回到行首 如果倒计时不刷新,再加上flush-True
time.sleep(1)
else:
print(' ','倒计时结束')

#20200930   文件的读取和写入
# 1、文件的打开方式(主要针对文本文档)
#2、文件内容读取
#3、文件内容写入
#4、文件扩展用法
# 打开文件用open()函数
# file_object = open(file_name,access_mode='r')
#以上函数格式中各个命名代表的意思分别是:
# file_name 文件路径:相对路径和绝对路径。
#access_mode:
# 读(定义时等于号指定的值,是缺省参数r)
# 写
# 读+写
# 文件路径的写法:有三种 2、3中更常用
# filename='G:/prthTest1,txt'
# filename='G:\prthTest1,txt' #加两个\是为了取消转义
# filename=r'G:prthTest1,txt' #r 取消转义 --只在python中用
# file_object---简写fo
# filename='J:\practice.txt'
# fo = open(filename)#加入参数encoding='utf-8'表示读的编码是中文
# # print(type(fo)) #打印对象类型,是个文件对象<class '_io.TextIOWrapper'>
# print(fo) #打印这个文件对象得到结果如下,有几个参数
##<_io.TextIOWrapper name='J:\practice.txt' mode='r' encoding='cp936'>
##打印结果意思:这是一个文件对象,路径是J盘下的那个名字,模式是只读,编码是cp936,
##那如果想读中文编码怎么办呢? 在fo = open(filename)中加入参数encoding='utf-8'
#文件的相对路径
#如果是进程文件,不是全路径,如:
# open('file1.txt) # open('./file1.txt')
# open('fold1/file1.txt')
# open('../file1.txt')
#../../表示的是上级目录的上级目录,以此类推
#相对于当前目录来寻找该文件,称之为相对路径

##文件内容读取
# fo.read()函数 该函数返回的是str
#文件模式--r
# 只是为了读取文件而打开文件。文件指针在文件的开头。这也是缺省的文件打开方式,即
#open('file') = open('file','r')
# 注意文件指针的移动,最后的关闭操作
#read()函数如果有具体读的长度,就读具体个数,写作: str1=foo.read(3)
# filname ='J:\practice.txt' #记住要先给路径赋变量名
# foo=open(filname,encoding='utf-8') #然后给open(路径变量名)这个函数赋予变量名
# str1=foo.read(2) #str=函数变量名.read(3)
# print(str1) #print(foo.rede(2)) 也是可以的 #打印结果:12(文件代码是123123123)
# print(foo.read(2)) #打印结果是:31,为什么呢?
#读了两个之后再读,是继续往后面读,因为光标的位置在第一次读之后移到了第三位前面
#同理,第三次读全部的话,就是读23123
#read()函数如果没有具体读的长度,就读全部,写作: str1=foo.read()
# filname ='J:\practice.txt' #记住要先给路径赋变量名
# foo=open(filname,encoding='utf-8') #然后给open(路径变量名)这个函数赋予变量名
# str1=foo.read() #str=函数变量名.read()
# print(str1) #打印结果:文件全部内容

# 读了之后文件关闭
# fo.close() #注意fo是文件对象,及open()函数赋予的变量名
# 如果文件被关闭了再去读,也是会报错的 如下:
# filname ='J:\practice.txt' #记住要先给路径赋变量名
# foo=open(filname,encoding='utf-8')
# #print(foo.read()) #读取的全部内容
# foo.close()
# print(foo.read()) #关闭了文件之后再去读取文件
# #报错了ValueError: I/O operation on closed file.

#---文件指针
# 文件指针的概念:即读取文件时,光标标记的那个就是指针,光标标记着文件读取的位置
# 指针就是接下来的读写操作开始的位置
# 如何获取到文件指针的位置呢 tell()函数 eg:
# filname ='J:\practice.txt' #记住要先给路径赋变量名
# foo=open(filname,encoding='utf-8') #然后给open(路径变量名)这个函数赋予变量名
# print(foo.tell())
# print(foo.read(3)) #print(foo.rede(2)) 也是可以的 #打印结果:12(文件代码是123123123)
# print(foo.tell()) #打印的光标位置是3,由此可见tell()函数获取到的光标位置是这一位的后面
# print(foo.read(2))

#--在代码中怎么移动光标达到读取文件指定内容呢?
# 文件指针的移动 seek()函数 使用方法:
# fo.seek(1,0) #seek()有两个参数:(移动到的位置,模式)
# 0模式意思是永远从文件指针开始的地方计算,即从0开始
# 0模式对应的是读'r'模式
# fo.seek(x)扩展用法:(开发用的比较多,测试做了解)
# 1模式是当前模式
# 2模式是尾部模式 用法举例子:
# filname ='J:\practice.txt' #记住要先给路径赋变量名
# foo=open(filname,encoding='utf-8') #然后给open(路径变量名)这个函数赋予变量名
# print(foo.tell())
# print(foo.read(2))
# print(foo.tell()) #这里的打印结果是2,表示指针移到了第二位后面
# print(foo.seek(5,0)) #打印结果5,说明光标移到了第五位后面
# print(foo.seek(5,1))
# 报错can't do nonzero cur-relative seeks,说明seek的1模式不支持read模式,怎么办呢?
# 以二进制方式去打开文件,seek的1模式和2模式都只支持二进制的.如下:
# finame='J:\practice.txt'
# foo=open(finame,'rb') #在open中添加参数'rb',表示已二进制方式打开文件
# print(foo.seek(1,1)) #打印结果是2,表示指针在第二位的前面
# print(foo.read(3)) #读的结果是b'231',b表示是以二进制读的,引号里面是读到的内容
# #print(foo.seek(1,1)) #打印的是5,代表指针已经移到了第五位的前面
# print(foo.seek(-1,1)) #打印结果是3,代表光标移到了第三位(因为读的时候读到的内容是1231,此时光标是在第四位)
# #第96行注销了再读-1,-1代表指针往前面移一位
# 将94-98都注销试试模式2:
# print(foo.seek(0,2)) #移动到了文件的末尾 打印得9
# print(foo.seek(-2,2)) #移动到了文件倒数第二个字符 打印得7,代表光标在第七位的后面
# print(foo.read()) # 打印结果是b'23'
# print(foo.seek(0)) #移动到头 打印得0
# print(foo.read()) #b'123123123'
# print(foo.seek(2,1)) #移动到当前指针往后两个字符,打印得11,因为之前读了文件全部内容,指针在第九位后面
#--读一行怎么读? readline()函数
# finame='J:\practice.txt'
# foo=open(finame)
#print(foo.readline()) #打印得:b'123123123'
#--读多行怎么读? readlines()函数
#print(foo.readlines()) #打印得:['22322 ', '323321']
#读取多行返回的是list列表
# 注:Windows--文件里面的换行是 两个长度
#字符串和Linux里面的换行符都是 ,一个长度
#--怎么去掉换行符呢?用splitlines()函数
# print(foo.read().splitlines()) #打印得['123123123', '22322', '323321'],也是列表

#2.文件的写的操作,如果文件不存在会新建,文件若存在会清空所有的内容
# 使用场景:输出本次使用的详细信息
# finame='J:\practice.txt'
# foo=open(finame,'w') #文件已经被清空了
# #写操作: 注意写入的是字符串
# foo.write('asdfghj') #本质不是写在磁盘,而是写在缓存,要关闭或者刷新文件(保存)才能写入
# foo.close() #关闭了,现在文件已经被写入了.功能同:foo.flush()
#--追加a写法:即不清空文件而追加内容。用法如后图:
# a:
# 只是为了在文件末尾追加内容而打开文件
# 如果文件存在,指针是在文件的末尾的
# 如果文件不存在,则创建一个新文件
# finame='J:\practice.txt'
# #foo=open(finame)
# #print(foo.read()) #先读一下文件内容:asdfghj
# # 注销掉131-133行之后用a模式打开文件.
# foo=open(finame,'a')
# foo.write('这是追加的内容')
# foo.flush()
# --如果想换行写追加的内容怎么办?a模式下怎么换行呢?
# 在追加的内容前面加上
# foo.write(' 这是追加的内容')
# foo.flush()
# 文件的扩展用法,再学三种模式,r+.w+.a+
# r+模式:为了读取并且写文件而打开文件,如果文件不存在会报错,文件的指针在文件的开头
# w+模式:为了读取并且写文件而打开文件,如果文件不存在,会建立一个新的文件,如果文件已经
# 存在,会清空文件内容,文件指针在文件的开头
# fil='d:\ordinary.txt'
# foa=open(fil,'w+',encoding='utf-8')
# foa.write('新建了这个文件并写入了这段话')
# a+模式:为了读取并且写入文件而打开文件,如果文件不存在,会建立一个新的文件,文件指针在
# 文件的末尾,很多OS上写操作永远在文件结尾进行,不管是否用例seek
# --如果需要同时打开多个文件怎么办?
# --一次打开多个文件的优势:可以省略一个close()的操作

# with open(文件路径) as 文件对象,open(文件路径) as 文件对象2
#在缩进里面写文件操作的代码 eg:
# fil='d:\ordinary.txt'和finame='J:\practice.txt' 现有这两个文件
#
# with open('d:\ordinary.txt','a',encoding='utf-8') as foo,open('J:\practice.txt','a',encoding='utf-8') as oa:
# foo.write('批量打开的第一个文件')
# foo.flush()
# oa.write('追加加载的批量打开的文件')
# oa.flush()






原文地址:https://www.cnblogs.com/66-liu/p/13814187.html