01文件自动化
1.路径操作
通常我们用os.path.join()
函数来创建文件名称字符串。
import os
os.path.join('Datawhale','docu')
os.getcwd() #取得当前工作路径的字符串
os.chdir()# 改变当前工作目录(必须提前创建好文件目录,不能直接新建)
os.path.abspath(path) # 将相对路径转换为绝对路径
os.path.isabs(path) # 判断是否是绝对路径,是返回True,不是则返回False
“绝对路径”,总是从根文件夹开始;“相对路径”,相对于程序的当前工作目录。
相对路径中,单个句点“.”表示当前目录的缩写,两个句点“…”表示父文件夹。
路径操作:
os.path.relpath(path,start)# 返回从start路径到path的相对路径的字符串。如果没提供start,就使用当前工作目录作为开始路径。
os.path.dirname(path) # 返回当前路径的目录名称。
os.path.basename(path) # 返回当前路径的文件名称。
caFilePath = 'D:\\Datawhale\\python办公自动化\\python课程画图.pptx'
os.path.split(caFilePath) #('D:\\Datawhale\\python办公自动化', 'python课程画图.pptx')
(os.path.dirname(caFilePath),os.path.basename(caFilePath)) # ('D:\\Datawhale\\python办公自动化', 'python课程画图.pptx')
caFilePath.split(os.path.sep) #['D:', 'Datawhale', 'python办公自动化', 'python课程画图.pptx']
路径有效性检查:
os.path.exists(path)# 如果path参数所指的文件或文件夹存在,则返回True,否则返回False。
os.path.isfile(path) # 如果path参数存在,并且是一个文件,则返回True,否则返回False。
os.path.isdir(path) # 如果path参数存在,并且是一个文件夹,则返回True,否则返回False。
2.文件及文件夹操作
os.makedirs()
可以创建所有必要的中间文件夹。
import os
os.makedirs('D:\\Datawhale\\practice') #查看目录,已创建,若文件夹已存在,不会覆盖,会报错
2.1查看文件的字节数以及给定文件夹中的文件和子文件夹
os.path.getsize(path) # 返回path参数中文件的字节数。
os.listdir(path) # 返回文件名字符串的列表,包含path参数中的每个文件。
如果想知道目录下所有文件的总字节数,可以同时使用os.path.getsize()
和os.listdir()
:
totalSize = 0
for filename in os.listdir('D:\\Datawhale\\python办公自动化'):
totalSize = totalSize + os.path.getsize(os.path.join('D:\\Datawhale\\python办公自动化',filename))
print(totalSize)
2.2文件读写过程
用open()
函数打开一个文件:
open(file,mode=r',buffering=-1,encoding=None,errors=None,newline=None,closefd=True,opener=None)
open()
函数参数介绍(常用前4个):
file
:指定了要打开的文件名称,应包含文件路径,不写路径则表示文件和当前py脚本在同一个文件夹。
buffering
:指定打开文件所用的缓冲方式,默认值-1表示使用系统默认的缓冲机制。文件读写要与硬盘交互,设置缓冲区的目的是减少CPU操作磁盘的次数,延长硬盘使用寿命。
encoding
:用于指定文件的编码方式,如GBK、UTF-8等,默认采用UTF-8,有时候打开一个文件全是乱码,这是因为编码参数和创建文件时采用的编码方式不一样。
mode
:指定了文件的打开模式。打开文件的基本模式包括r、w、a,对应读、写、追加写入。附加模式包括b、t、+,表示二进制模式、文本模式、读写模式,附加模式需要和基本模式组合才能使用,如“rb”表示以二进制只读模式打开文件,“rb+”表示以二进制读写模式打开文件。
**注意:**凡是带w的模式,操作时都要非常谨慎,它首先会清空原文件,但不会有提示。凡是带r的文件必须先存在,否则会因找不到文件而报错。
读取文件内容:
read():以原格式返回全部文本
readline(): 只返回第一行文本
readlines(): 以列表的格式返回全部文本,文本的第几行对应列表的第几个元素
sonnetFile = open('D:\\Datawhale\\python办公自动化\\hello.txt')
sonnetFile.readlines()
写入文件:
“写模式”将覆写原有的文件,从头开始。“添加模式”将在已有文件的末尾添加文本。
baconFile = open('bacon.txt','w')
baconFile.write('Hello world!\n')
baconFile.close()
注意:write()
方法不会像print()函数那样,在字符串的末尾自动添加换行字符。必须自己添加该字符。
案例:统计字母出现的频率
from collections import Counter
my_list = []
punctuation=',.!?\,。!?、()【】<>《》=:+-*“”...\n'
with open('bacon.txt','r') as f:
for line in f:
for word in line:
if word not in punctuation:
my_list.append(word)
counter = Counter(my_list)
counter
2.3保存变量
1.shelve模块
用shelve
模块,可以将Python中的变量保存到二进制的shelf
文件中。这样,程序就可以从硬盘中恢复变量的数据。
import shelve
shelfFile = shelve.open('mydata')
cats = ['Zonphie','Pooka','Simon']
shelfFile['cats'] = cats
shelfFile.close()
在Windows上运行前面的代码,我们会看到当前工作目录下有3个新文件:mydata.bak、mydata.dat和mydata.dir。
重新打开这些文件,取出数据。注意:shelf
值不必用读模式或写模式打开,因为打开后,既能读又能写。
shelfFile = shelve.open('mydata')
type(shelfFile)# shelve.DbfilenameShelf
shelfFile['cats']# ['Zonphie', 'Pooka', 'Simon']
shelfFile.close()
就像字典一样,shelf值有keys()和values()方法,返回shelf中键和值的类似列表的值。但是这些方法返回类似列表的值,却不是真正的列表,所以应该将它们传递给list()函数,取得列表的形式。
shelfFile = shelve.open('mydata')
list(shelfFile.keys())# ['cats']
list(shelfFile.values())# [['Zonphie', 'Pooka', 'Simon']]
shelfFile.close()
2.用pprint.pformat()函数保存变量
pprint.pformat()
函数返回要打印的内容的文本字符串,这个字符串既易于阅读,也是语法上正确的Python代码。
假如,有一个字典,保存在一个变量中,希望保存这个变量和它的内容,以便将来使用。pprint.pformat()
函数将提供一个字符串,我们可以将它写入.py文件。这个文件可以成为我们自己的模块,如果需要使用存储其中的变量,就可以导入它。
import pprint
cats = [{'name':'Zophie','desc':'chubby'},{'name':'Pooka','desc':'fluffy'}]
pprint.pformat(cats)
fileObj = open('myCats.py','w')
fileObj.write('cats = '+pprint.pformat(cats)+'\n')
fileObj.close()
import语句导入的模块本身就是Python脚本。如果来自pprint.pformat()的字符串保存为一个.py文件,该文件就是一个可以导入的模块。
import myCats
myCats.cats # [{'desc': 'chubby', 'name': 'Zophie'}, {'desc': 'fluffy', 'name': 'Pooka'}]
myCats.cats[0]# {'desc': 'chubby', 'name': 'Zophie'}
myCats.cats[0]['name'] # 'Zophie'
3.组织文件
查找一个文件夹,里面有几十个、几百个、甚至上千个文件,需要手工进行复制、改名、移动或压缩。shutil
(或称为shell工具)模块中包含一些函数,可以在Python程序中复制、移动、改名和删除文件。要使用shutil
的函数,首先需要import shutil
1.复制文件和文件夹
shutil.copy(source, destination)
:将路径source处的文件复制到路径 destination处的文件夹(source 和 destination 都是字符串),并返回新复制文件绝对路径字符串。
其中destination可以是:
1)一个文件的名称,则将source文件复制为新名称的destination
2)一个文件夹,则将source文件复制到destination中
3)若这个文件夹不存在,则将source目标文件内的内容复制到destination中,若destination文件夹不存在,则自动生成该文件。(慎用,因为会将source文件复制为一个没有扩展名的名字为destination的文件,这往往不是我们希望的)
"""
这里如果路径下没有bacon.txt,可以从当前代码文件路径下找到bacon.txt,
将其移至指定路径学习使用
"""
import shutil
import os
shutil.copy('D:\\Datawhale\\python办公自动化\\bacon.txt', 'D:\\Datawhale\\practice')
注:destination处的文件夹为新创建的文件夹,如已存在,则会报错
2.文件和文件夹的移动与改名
shutil.move(source, destination)
:将路径 source 处的文件/文件夹移动到路径destination,并返回新位置的绝对路径的字符串。
1)如果source和destination是文件夹,且destination已存在,则会将source文件夹下所有内容复制到destination文件夹中。移动。
2)如果source是文件夹,destination不存在,则会将source文件夹下所有内容复制到destination文件夹中,source原文件夹名称将被替换为destination文件夹名。 移动+重命名
3)如果source和destination是文件,source处的文件将被移动到destination处的位置,并以destination处的文件名进行命名,移动+重命名。
注意:如果destination中有原来已经存在同名文件,移动后,会被覆写,所以应当特别注意。
import shutil
shutil.move('D:\\Datawhale\\practice','D:\\Datawhale\\docu')
3.永久删除文件和文件夹
os.unlink(path)
: 删除path处的文件。
os.rmdir(path)
: 删除path处的文件夹。该文件夹必须为空,其中没有任何文件和文件夹。
shutil.rmtree(path)
:删除 path 处的文件夹,它包含的所有文件和文件夹都会被删除。
#建议先指定操作的文件夹,并查看
os.chdir('D:\\Datawhale\\docue')
os.getcwd()
import os
for filename in os.listdir():
print(filename)
os.unlink(filename)
# 可以看到bacon.txt已经被删除
for filename in os.listdir():
print(filename)
4. 用send2trash模块安全地删除
用第三方的send2trash
模块,可以将文件或文件夹发送到计算机的垃圾箱或回收站,而不是永久删除。
import send2trash
send2trash.send2trash('bacon.txt')
5.遍历目录树
os.walk(path)
:传入一个文件夹的路径,在for循环语句中使用os.walk()
函数,遍历目录树,和range()函数遍历一个范围的数字类似。不同的是,os.walk()
在循环的每次迭代中,返回三个值:
1)当前文件夹称的字符串。
2)当前文件夹中子文件夹的字符串的列表。
3)当前文件夹中文件的字符串的列表。
按照上图目录树,创建相应的文件:
import os
for folderName, subFolders,fileNames in os.walk('D:\\animals'):
print('The current folder is ' + folderName)
for subFolder in subFolders:
print('Subfolder of ' + folderName+':'+subFolder)
for filename in fileNames:
print('File Inside ' + folderName+':'+filename)
print('')
# The current folder is D:\animals
# Subfolder of D:\animals:cats
# Subfolder of D:\animals:dogs
# File Inside D:\animals:Miki.txt
# The current folder is D:\animals\cats
# File Inside D:\animals\cats:catNames.txt
# File Inside D:\animals\cats:zophie.jpg
# The current folder is D:\animals\dogs
# Subfolder of D:\animals\dogs:wolf
# The current folder is D:\animals\dogs\wolf
# File Inside D:\animals\dogs\wolf:Taidi.txt
6.用zipfile模块压缩文件
利用zipfile模块中的函数,Python程序可以创建和打开(或解压)zip文件。
创建和添加到zip文件
zipfile.ZipFile('filename.zip', 'w')
:以写模式创建一个压缩文件
ZipFile
对象的write('filename','compress_type=zipfile.ZIP_DEFLATED')
方法:如果向write()
方法中传入一个路径,Python 就会压缩该路径所指的文件, 将它加到 ZIP 文件中。 如果向write()
方法中传入一个字符串,代表要添加的文件名。第二个参数是“压缩类型”参数,告诉计算机用怎样的算法来压缩文件。可以总是将这个值设置为 zipfile.ZIP_DEFLATED
(这指定了 deflate 压缩算法,它对各种类型的数据都很有效)。
注意:写模式会擦除zip文件中所有原有的内容。如果只希望将文件添加到原有的zip文件中,就要向zipfile.ZipFile()
传入’a’作为第二个参数,以添加模式打开 ZIP 文件。
将上述章节中animals文件夹进行压缩。创建一个example.zip的zip文件,并向其中添加文件:
## 2 创建一个example.zip的压缩文件,将animals文件夹下所有文件进行压缩。
import zipfile
import os
newZip = zipfile.ZipFile('example.zip','w')
for folderName, subFolders,fileNames in os.walk('D:\\animals'):
for filename in fileNames:
newZip.write(os.path.join(folderName,filename),compress_type=zipfile.ZIP_DEFLATED)
newZip.close()
读取zip文件
调用zipfile.ZipFile(filename)
函数创建一个ZipFile
对象(注意大写字母Z和F),filename是要读取zip文件的文件名。
ZipFile
对象中的两个常用方法:
namelis()
方法,返回zip文件中包含的所有文件和文件夹的字符串列表。
getinfo()
方法,返回一个关于特定文件的ZipInfo
对象。
ZipInfo
对象的两个属性:file_size
和compress_size
,分别表示原来文件大小和压缩后文件大小。
import zipfile,os
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.namelist()
# ['animals/Miki.txt',
# 'animals/cats/catNames.txt',
# 'animals/cats/zophie.jpg',
# 'animals/dogs/wolf/Taidi.txt']
catInfo = exampleZip.getinfo('animals/Miki.txt')
catInfo.file_size # 4
catInfo.compress_size # 6
print('Compressed file is %s x smaller!' %(round(catInfo.file_size/catInfo.compress_size,2)))
# Compressed file is 0.67 x smaller!
exampleZip.close()
7.从zip文件中解压缩
ZipFile
对象的 extractall()
方法:从zip文件中解压缩所有文件和文件夹,放到当前工作目录中。也可以向extractall()
传递的一个文件夹名称,它将文件解压缩到那个文件夹, 而不是当前工作目录。如果传递的文件夹名称不存在,就会被创建。
ZipFile
对象的 extract()
方法:从zip文件中解压单个文件。也可以向 extract()传递第二个参数, 将文件解压缩到指定的文件夹, 而不是当前工作目录。如果第二个参数指定的文件夹不存在, Python 就会创建它。extract()的返回值是被压缩后文件的绝对路径。
import zipfile, os
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.extractall('.\zip')
exampleZip.close()
exampleZip = zipfile.ZipFile('example.zip')
exampleZip.extract('animals/Miki.txt')
exampleZip.extract('animals/Miki.txt', 'D:\\animals\\folders')
exampleZip.close()
4.特定文件查找
glob
找当前目录下全部的.txt文档:
import glob
glob.glob('*.txt')
这里主要是写匹配条件,“*”匹配任意个字符,“?”匹配单个字符,也可以用“[]”匹配指定范围内的字符,如[0-9]匹配数字。
- glob.glob(‘[0-9].*’)可以匹配当前目录下文件名中带有数字的文件。
- glob.glob(r’G:*')可以获取G盘下的所有文件和文件夹,但是它不会进一步列明文件夹下的文件。也就是说,其返回的文件名只包括当前目录里的文件名,不包括子文件夹里的文件
fnmatch模块
使用fnmatch可以完成更为复杂的文件名匹配。它有4个函数,分别是fnmatch、fnmatchcase、filter和translate,其中最常用的是fnmatch函数,其语法如下。
- fnmatch.fnmatch(filename,pattern)
pattern表示匹配条件,测试文件名filename是否符合匹配条件。
下面找出目标文件夹里所有结尾带数字的文件:
import os,fnmatch
path = os.getcwd() # 获取当前代码文件所在目录
for foldname, subfolders,filenames in os.walk(path):
for filename in filenames:
if fnmatch.fnmatch(filename,'*[0-9].*'):
print(filename)
fnmatchcase和fnmatch函数类似,只是fnmatchcase函数强制区分字母大小写。
以上两个函数都返回True或者False,filter函数则返回匹配的文件名列表,其语法如下:
- fnmatch.filter(filelist,pattern)
hashlib模块
随着计算机中文件越来越多,我们需要找出重复文件。重复文件可能有不同的文件名,不能简单用文件名和文件大小来判断。从科学角度,最简单的办法就是通过MD5来确定两个文件是不是一样的。Python自带的hashlib库里提供了获取文件MD5值的方法。
import hashlib
m = hashlib.md5()
f = open('bacon.txt','rb')
m.update(f.read())
f.close()
md5_value = m.hexdigest()
print(md5_value)
电子文件容易被篡改或者伪造,在出现纠纷时,怎么提供有力的证据来证明文件的真实性?一个可行的办法就是制作文件后对整个文件生成MD5值。一旦MD5值生成之后,文件发生过任何修改,MD5值都将改变,通过此方法可以确定文件是否被篡改过。