目录
1.文件打开关闭
2.文件读写
3.应用:文件备份脚本
4.文件定位
5.模块介绍
6.os模块操作文件
7.time、datetime模块
8.模块的制作、发布、安装
导读
文件操作是很常见的功能,我们python当然也支持,python自带文件的基本操作方法,但是借助os等模块更加方便快捷。在学习过程中,我们时不时会用到模块,这里也将详细讲解模块、常用模块、以及怎样制作、发布和安装模块。
学习目的
1.通过使用文件的打开关闭、读写等,完成文件备份脚本(重点)
2.通过文件定位的相关方法,完成精确控制文件读写
3.使用os模块操作文件,提高效率(重点)
4.使用time、datetime模块完成时间相关操作(重点)
5.通过模块的制作、发布、安装,进一步明白模块的意义
文件操作一般步骤
打开文件
读/写文件
保存文件
关闭文件
在Python中打开文件使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
语法格式:
open('文件名称','打开模式’)
示例:
#'w'模式 fobj=open('./Test.txt','w') fobj.write('在苍茫的大海上有一首诗\r\n') fobj.close() #以二进制写入 fobj=open('./Test.txt','wb') fobj.write('在乌云和大海之间'.encode('utf-8')) fobj.close() #追加数据 fobj=open('./Test.txt','a') fobj.write('在乌云和大海之间\r\n') fobj.write('海燕像黑色的闪电') fobj.close()
文件打开模式
'r' open for reading (default) 'w' open for writing, truncating the file first 'x' create a new file and open it for writing 'a' open for writing, appending to the end of the file if it exists 'b' binary mode 't' text mode (default) '+' open a disk file for updating (reading and writing) 'U' universal newline mode (deprecated)
语法格式:
close() 方法关闭文件
示例:
f = open('text.txt','w') f.close()
注意: 打开一个文件之后,一定要关闭,否则后面无法继续操作这个文件
with 上下文管理
with 语句,不管在处理文件过程中是否发生异常,都能保证 with 语句执行完毕后已经关闭打开的文件句柄。
#写数据 fobj=open('./Test.txt','w') fobj.write('在乌云和大海之间\n') fobj.write('海燕像黑色的闪电\n') fobj.close() #with处理 with open('Test.txt','a') as f: #追加 f.write('我觉得python非常好') with open('Test.txt','r') as f: #读 print(f.read())
运行结果
在乌云和大海之间 海燕像黑色的闪电 我觉得python非常好
2.1写文件
写入文件 write() 方法,参数就是需要写入的内容。
读取文件 read() ,将文件的内容全部读取出来。
fobj=open('./Test.txt','w') fobj.write('在乌云和大海之间\n') fobj.write('海燕像黑色的闪电\n') fobj.close() #读数据操作 f=open('Test.txt','r') #print(f.read())# 读取所有的数据 # print(f.read(12))#读取12个数 # print(f.read())#读取剩下的全部 # print(f.readline()) #读取一行 # print(f.readline()) #再读取一行 print(f.readlines()) #读取所有行,返回的列表
读取指定字符个数 read(num)传入一个数字做参数,表示读取指定字符个数。
content = f.read(2) # 读取两个字符
readlines() 按行读取,一次性读取所有内容,返回一个列表,每一行内容作为一个元素。
content = f.readlines() # 一次性读取所有内容,返回一个列表,列表元素为每一行内容
readline() 按行读取,但是一次只读取一行
content = f.readline() # 按行读取,一次读取一行
二进制rb 的读取方法
fobj=open('./Test.txt','w') fobj.write('在乌云和大海之间\n') fobj.write('海燕像黑色的闪电\n') fobj.close() #读数据操作 f=open('Test.txt','rb') #二进制读取 data=f.read() print(data) #解码之前 print(data.decode('gbk'))# 以gbk解码之后 f.close() #关闭文件
运行结果
b'\xd4\xda\xce\xda\xd4\xc6\xba\xcd\xb4\xf3\xba\xa3\xd6\xae\xbc\xe4\r\n\xba\xa3\xd1\xe0\xcf\xf1\xba\xda\xc9\xab\xb5\xc4\xc9\xc1\xb5\xe7\r\n' 在乌云和大海之间 海燕像黑色的闪电
小结:
文件读写的几种操作方式
read r r+ rb rb+
r r+ 只读,使用普通读取场景
rb rb+ 适用于 文件 图片 视频 音频这样文件读取
write w w+ wb wb+ a ab
w w+ wb wb+ 每次都会创建新的文件,覆盖掉原来的文件,二进制读写的时候 要注意编码问题,默认情况下,我们写入文件的编码是gbk
a ab a+ 在原有文件的基础之后【文件指针的末尾】去追加,每次不会去创建一个新的文件
需求
1.利用脚本完成自动备份,要求用户输入文件名称,完成自动备份
def copyFile(): #接收用户输入的文件名 old_file=input('请输入需要备份的文件名:') file_list=old_file.split('.') #构造新的文件名,加上备份的后缀 new_file=file_list[0]+'备份'+file_list[1] old_f=open(old_file,'r') #打开需要备份的文件 new_f = open(new_file, 'w') #以写的模式去打开新的文件,不存在则创建 content=old_f.read()#将文件内容读取出来 new_f.write(content) old_f.close() new_f.close() copyFile()
2如果处理超大文件,一次将全部内容读取出来显然是不合适的,在需求1的基础上改进下代码,让它备份大文件也不会导致内存被占满。
def copyBigFile(): #接收用户输入的文件名 old_file=input('请输入需要备份的文件名:') file_list=old_file.split('.') #构造新的文件名,加上备份的后缀 new_file=file_list[0]+'备份'+file_list[1] try: #监视要处理的逻辑 with open(old_file,'r') as old_f,open(new_file,'w') as new_f: while True: content=old_f.read(1024) #一次读取1024个字符 new_f.write(content) if len(content)<1024: break except Exception as msg: print(msg) copyBigFile()
tell()
文件定位,指的是当前文件指针读取到的位置,光标位置。在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取
#tell 返回指针当前所在的位置 with open('Test.txt','r') as f: print(f.read(3)) print(f.tell()) print(f.read(2)) #累计5个汉字,10个字节 print(f.tell())
运行结果
m在乌 说明:英文占用1个字符,汉字占用2个字符 5 云和 9 说明:累计“m在乌云和”,合计9个字符
truncate() 保留前**位
#truncate 可以对源文件进行截取操作 print('----截取之前的数据---') fobjB=open('Test.txt','r') print(fobjB.read()) fobjB.close() print('----截取之后的数据---') fobjA=open('Test.txt','r+') fobjA.truncate(16) #保留前16个字符 print(fobjA.read()) fobjA.close()
输出结果
----截取之前的数据--- 在乌云和大海之间 海燕像黑色的闪电 我觉得python非常非常好 ----截取之后的数据--- 在乌云和大海之间
seek()
如果在操作文件的过程,需要定位到其他位置进行操作,用seek()。
seek(offset, from)有2个参数,offset,偏移量单位字节,负数是往回偏移,正数是往前偏移,from位置:0表示文件开头,1表示当前位置,2表示文件末尾
with open('Test备份txt','rb') as f: print(f.read().decode('gbk')) print('-----------------------------') f.seek(0, 0) #从文件的头开始 data=f.read(2) print(data.decode('gbk')) #在 f.seek(-2,1) #当前位置,向左移动2位,相当于光标又设置到了0的位置 print(f.read(4).decode('gbk')) #上一个代码后,回到初始位置,再读4位 在乌 f.seek(2,1) #在’乌‘往后面移动2个字符到’云‘ print(f.read(4).decode('gbk')) #在‘云’往后读4个字符到‘和大’ f.seek(-4, 2) # 在末尾向左移动4个字符,到‘常’ print(f.read(4).decode('gbk')) #在‘常’往后读4个字符到‘常好’
运行结果
在乌云和大海之间 海燕像黑色的闪电 我觉得python非常非常好 ----------------------------- 在 在乌 和大 常好
注意:需要用二进制‘rb’的模式打开
用“r”这种模式打开的文件,在文本文件中,没有使用二进制的选项打开文件,只允许从文件的开头计算相对位置,从文件尾部计算或者当前计算的话,就会引发异常
import导入模块
我们经常说Python有强大的第三方库,有很多常用功能Python提供自带的内置模块。 简单的讲模块就是封装了一堆函数的py文件,就像是一个工具包,要使用里面的工具,得先将工具包那过来。模块也是一样,在程序中需要用到模块得先将模块导入。
在Python中导入模块使用import 关键字。比如我们导入一个时间模块time,获取当前时间。 模块导入一般放在文件最前面。
示例
import time print(time.ctime()) ''' 调用模块中的函数 返回现在的时间 Sun Nov 7 15:25:59 2021 '''
调用模块的方法,格式:模块名.函数名,这样调用可以防止不同模块中有同名方法导致错误。
import到首次导入模块的时候 会发生如下3步操作
1.打开模块的文件
2.执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
3.在程序中会有一个模块名称来指向模块的名称空间
搜索路径
当解释器遇到import关键字,如果模块在当前的搜索路径就会被导入。 查看import导入的搜索路径,导入模块时会优先搜索当前目录下是否有这个名字的模块,所以在模块命名的时候不要与系统中的模块有重名。
(1)、当前目录
(2)、如果当前目录没有,到环境变量中搜索,可以用sys模块中的path变量查看所有路径。
(3)、如果都找不到,搜索默认路径,linux系统,默认路径一般为/usr/local/lib/python/
from ... import 导入模块的方法
一个模块可能会存在很多函数,如果只想导入其中几个函数,可以使用from xx import xx 方式导入,优点:不用加前缀,方法可以直接使用 缺点:容易重名,产生冲突
示例:只想导入time模块中的ctime,time两个方法,可以这样导入。
from time import ctime,time ''' 从time模块中导入ctime,time ''' print(ctime()) #直接用 不用加time.ctime() print(time())
输出结果
Sun Nov 7 15:40:26 2021 1636270826.3767643
使用from导入,如果函数名相同,后面导入的会覆盖前面导入的。
把模块中的所有函数一次性全部导入
语法格式:from xxx import *
示例:
from time import *
as 给模块取别名
有时候导入的模块名称很长,调用的时候很不方便,这个使用就可以用as给这个模块取别名。
import time as myTime #给模块取了别名,原来的time就失效了 print(myTime.ctime()) #就不能使用原来的time名称了
调用的时候不难使用原来的名称了,要使用别名
概述
对文件进行重命名、删除等一些操作,在python中可以利用os模块。os模块提供一些系统级别的操作命令
os.getcwd() #返回当前工作目录
os.chdir(path) #改变工作目录
os.listdir(path=".") #列举指定目录中的文件名("."表示当前目录,“..”表示上一级目录
os.mkdir(path) #创建建单层目录,如果该目录已存在则抛出异常
os.makedirs(path) #递归创建多层目录,如该目录已存在抛出异常
os.remove(path) #删除文件
os.rmdir(path) #删除单层目录,如该目录非空则抛出异常
os.removedirs(path) #递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常
os.rename(old,new) #将文件old重命名为new
os.system(command) #运行系统shell命令
os.walk(top) #遍历top路径以下所有子目录,返回一个三元组:(路径,[包含目录],[包含文件])
os.curdir #属性,表示当前目录
os.pardir #属性,表示上一级目录
os.sep #属性,输出操作系统特定的路径分隔符(win下为'\\',Linux下为'/')
os.linesep #属性,当前平台使用的行终止符(Win下为‘\r\n’,Linux下为'\n')
os.name #属性,指待当前使用的操作系统
路径方法
os.path.basename(path) #去掉目录路径,单独返回文件名
os.path.dirname(path) #去掉文件名,单独返回目录路径os.path.join(path1[,],path2[,...]) #将path1,path2各部分组成一个路径名
os.path.split(path) #分割文件名和路径,返回一个(f_path,f_name)元组,
# 如果完全使用目录,它也会将最后一个目录作为文件名分离
os.path.splitext(path) #分离文件名和后缀名,返回(f_name,f_extension)元组,
# 如果完全使用目录,它也会将最后一个目录作为文件名分离
os.path.getsize(file) #返回指定文件的尺寸,单位是字节
os.path.getatime(file) #返回指定文件最近的访问时间
#(浮点型秒数,可用time模块的gmtime()或localtime()函数换算)
os.path.getctime(file) #返回指定文件的创建时间
os.path.getmtime(file) #返回指定文件最新的修改时间
os.path.exists(path) #判断指定路径是否存在(目录或者文件)
os.path.isabs(path) #判断是否为绝对路径
os.path.isdir(path) #判断指定路径是否存在且是一个目录
os.path.isfile(path) #判断指定路径是否存在且是一个文件
os.path.islink(path) #判断指定路径是否存在且是一个符号链接
os.path.ismount(path) #判断指定路径是否存在且是一个挂载点
os.path.samefile(path1,path2) #判断path1,path2是否指向同一个文件
修改文件名:rename(需要修改的文件名,新的文件名)
import os #修改文件名:rename(需要修改的文件名, 新的文件名) os.rename(r'C:\Users\MLoong\Desktop\89.xlsx',r'C:\Users\MLoong\Desktop\98.xlsx')
删除文件:remove(待删除的文件名)
import os os.remove(r'C:\Users\MLoong\Desktop\98.xlsx')
创建文件夹: mkdir(文件夹名称)
import os os.mkdir(r'C:\Users\MLoong\Desktop\文件夹88')
删除文件夹:rmdir(文件夹名称)
只能删除空目录
import os os.rmdir(r'C:\Users\MLoong\Desktop\文件夹88')
删除非空目录
import shutil shutil.rmtree(r'C:\Users\MLoong\Desktop\文件夹')
获取当前程序地址:getcwd()
import os print(os.getcwd())
运行结果
C:\Users\MLoong\PycharmProjects\pythonProject5
路径拼接: os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回
import os print(os.path) print(os.path.join(os.getcwd(),'venv'))
运行结果
C:\Users\MLoong\PycharmProjects\pythonProject5\venv
打印文件目录-第一级文件,不会继续深入查找
import os #获取python中的目录列表 listRS=os.listdir('d:/') print(listRS) #返回的是列表,电脑D盘中所以文件的名称 for item in listRS: print(item) print('--------新版方法------------') with os.scandir('d:/') as entries: for entry in entries: print(entry.name)
打印结果
['$RECYCLE.BIN', '360Downloads', '360极速浏览器下载', 'BaiduNetdiskDownload'] $RECYCLE.BIN 360Downloads 360极速浏览器下载 BaiduNetdiskDownload --------新版方法------------ $RECYCLE.BIN 360Downloads 360极速浏览器下载 BaiduNetdiskDownload
若只打印文件名的话
print('--------打印出文件名------------') basePath='d:/' for entry in os.listdir(basePath): if os.path.isfile(os.path.join(basePath,entry)): print(entry)
time 模块的使用
time.sleep(num) ,让程序执行暂停,num单位是秒
import time time.sleep(5) #程序暂停5s
time.time() #返回时间戳时间戳
import time print(time.time()) #返回时间戳 1636277714.4327455 print(time.ctime()) #字符串格式 Sun Nov 7 17:35:14 2021 print(time.asctime()) #返回格式为 Sun Nov 7 17:35:14 2021 print(time.localtime()) #返回本地时间 print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))
运行结果
1636277924.8614864 Sun Nov 7 17:38:44 2021 Sun Nov 7 17:38:44 2021 time.struct_time(tm_year=2021, tm_mon=11, tm_mday=7, tm_hour=17, tm_min=38, tm_sec=44, tm_wday=6, tm_yday=311, tm_isdst=0) 2021-11-07 17:38:44
time 模块的使用
时间格式化输出
%y 两位数的年份表示(00-99) | %Y 四位数的年份表示(000-9999) | %m 月份(01-12) |
%d 月内中的一天(0-31) | %H 24小时制小时数(0-23) | %I 12小时制小时数(01-12) |
%M 分钟数(00=59) | %S 秒(00-59) | %a 本地简化星期名称 |
%A 本地完整星期名称 | %b 本地简化的月份名称 | %B 本地完整的月份名称 |
%c 本地相应的日期表示和时间表示 | %j 年内的一天(001-366) | |
%p 本地A.M.或P.M.的等价符 | %U 一年中的星期数(00-53)星期天为星期的开始 | |
%w 星期(0-6),星期天为星期的开始 | %W 一年中的星期数(00-53)星期一为星期的开始 | |
%x 本地相应的日期表示%X 本地相应的时间表示 | %Z 当前时区的名称%% %号本身 |
datetime模块
datetime模块主要用于时间计算 。
import datetime print(datetime.datetime.now()) #当前时间+3天 print(datetime.datetime.now()+datetime.timedelta(3)) #当前时间+3小时 print(datetime.datetime.now()+datetime.timedelta(hours=3)) #当前时间+30分 print(datetime.datetime.now()+datetime.timedelta(minutes=30))
输出结果
2021-11-07 17:48:02.662048 2021-11-10 17:48:02.662048 2021-11-07 20:48:02.662048 2021-11-07 18:18:02.662048
模块的定义:在python中,一个.py文件就是一个模块
作用:可以是我们有逻辑的去组织我们的python代码,以库的形式去封装功能,非常方便的去让调用者使用
可以定义函数,类,变量也可以包含可执行的代码
注意:不同的模块可以定义相同的变量名,但是每个模块中的变量名作用域只是在本模块中
模块分类:
内置模块 自定义模块 第三方的模块
模块的制作
(1)、Python文件都可以作为一个模块,模块的名字就是文件的名字。 比如创建一个test.py文件,文件中创建一个add函数。test.py就是一个模块。
创建模块
#创建一个名为 modeltest 的模块 def add(x,y): return x+y #测试 if __name__=='__main__': #在调用的时候 可以不显示测试的结果 res=add(2,5) print('测试模块,%s'%res)
使用模块
import modeltest #第一种导入方式 #from modeltest import add #第二种导入方式 #from modeltest import * res=modeltest.add(2,3) print(res)
模块的发布
平时使用第三方模块是其他开发者发布出来,需要安装后调用。下面我们来学习怎么去发布一个模块。
(1)、将写好的包放到一个modeltest/目录下
(2)、在modeltest/目录下创建一个文件setup.py文件
(3)、 创建模块
(4)、生成压缩包
(5)、tree 看下modeltest/目录下的结构
模块的安装
(1)、将上一节生成的压缩包复制到桌面解压
tar -zxvf my_module-1.0.tar.gz
解压后在桌面会生成一个文件夹my_module-1.0
(2)、进入my_module-1.0文件夹
cd my_module-1.0
(3)、执行命令安装 python setup.py install
(4)、查看是否安装成功
在python的安装目录下的site-packages目录下
(5)、模块引入,可以导入说明安装成功