python文件操作整理

python读写文件有三种形式:读、写、追加

一、读模式 r 和读写模式 r+

1、读模式 r
特点:只能读不能写,文件不存在时会报错
2、读写模式 r+
特点:可以读也可以写,是覆盖写,会把文件最前面的内容覆盖;文件不存在时会报错

二、写模式 w 和写读模式 w+

1、写模式 w
特点:只能写不能读;写的时候会把原来的文件内容清空;当文件不存在时,会创建新文件
2、写读模式 w+
特点:可以写也可以读;写的时候会把原来的文件内容清空;当文件不存在时,会创建新文件

三、追加模式 a和追加读模式 a+

1、追加模式 a
特点:不能读;是追加写,即在原内容末尾添加新内容;文件不存在时创建新文件
2、追加读模式 a+
特点:可读可写;是追加写,即在原内容末尾添加新内容;文件不存在时创建新文件

python文件操作方法

一、文件操作函数

1、打开文件
f = open(file,'parameter2','parameter3')
打开指定的文件file,file默认路径是程序所在的位置,也可以指定file的路径。

  • file:文件名
  • parameter2:模式
  • parameter3:编码方式

用with方式打开文件,在使用完文件后它将自动关闭文件

with open('test.txt') as file:

2、读文件
content = f.read()
一次性读取文件的全部内容

content = f.readline()

一次读取一行,读取的内容包括换行符

list = f.readlines()

返回由文件中的文本行组成的列表,换行符也包含在列表每一项内。
3、写文件

f.write('Hello, world!')

write()方法写入的内容不会自动换行,但可使用换行符“\n”。调用f.write()方法写文件时,操作系统不会立刻将数据写入磁盘,而是放到内存缓存起来,空闲时在慢慢写入,只有调用close()方法时,操作系统才会将全部数据写入磁盘。所以我们可以调用with语句来自动关闭文件。

with open('test.txt', 'w') as f:
    f.write('Hello, world!')

4、关闭文件

f.close()

对一个文件不再进行操作时调用

二、os模块常用函数

1、os.path:路径操作相关函数

  • os.path.isfile(filepath):检查路径是否是一个文件,返回true或false
  • os.path.join(dir1,dir2):将两个目录名合并成新路径
  • os.path.split(filepath):将filepath的最后一个组件提取出来,该函数返回包含两个值的元组
  • os.path.splitext(filename):将一个文件的名称和扩展名分开,可以用来判别文件类型
  • os.path.normpath(path):规范path字符串形式
  • os.path.abspath(filename):将相对路径转换成绝对路径
  • os.path.exists(path):检查路径是否存在,返回tree或者false
  • os.path.isdir(filepath):检查路径是否是指向一个文件夹
  • os.path.getsize(filepath):以字节为单位返回该文件的大小
  • os.path.getmtime(filepath):返回上次被修改的时间
  • os.path.isabs():判断是否是绝对路径
  • os.path.dirname():获取路径名
  • os.path.basename():获取文件名

2、os.listdir(path)
返回path目录下所有的文件或子文件夹
3、os.remove(file)
删除文件
4、os.mkdir(dir)
创建目录,要创建的父目录必须存在
5、os.makedirs(dir)
创建目录,若父目录不存在则创建父目录
6、os.rmdir(dir)
仅能删除空目录
7、os.rename(file_path,file_new_path)
将文件重命名

三、shutil模块常用函数

1、shutil.move(file_path,save)
将文件移动到save文件夹下
2、shutil.copy(file_path,save)
将文件保存在save文件夹下

python操作xml文件

什么是xml?

xml是可扩展标记语言,被设计用来传输和存储数据,xml是一套定义语义标记的规则,这些标记将文档分成许多部件,并对这些部件进行标识。
xml文档形成一种树结构,它从根部开始,然后扩展到枝叶。



		
		.....
	

第一行是xml声明,它定义了xml的版本和使用的编码
第二行描述的就是xml文档的根元素
接下来的就是描述根的子元素

python对xml的解析

python有三种方式解析xml,包括SAX、DOM以及ElementTree

一、使用SAX解析xml

SAX是一种基于事件驱动的api,利用SAX解析xml文档需要解析器和事件处理器,解析器负责读取xml文档并向事件处理器发送事件,事件处理器则负责对事件做出响应,对传递的xml数据进行处理。

二、使用xml.dom解析xml

DOM(文档对象模型)的解析器在解析xml文档时,一次性读取整个文档,把文档中的所有元素保存在内存中的一个文档树结构里,之后利用DOM提供的函数来读取和修改文档的结构和内容,也可以把修改过的内容写入xml文件。
(1)导入模块:import xml.dom.minidom
(2)加载xml文件到内存:dom = xml.dom.minidom.parse("test.xml")
(3)获取根节点:root = dom.documentElement
(4)获得子标签:tag = root.getElementsByTagName('tag')
每一个结点都有它的nodeName,nodeValue,nodeType属性
例如:root.nodeNameroot.nodeValueroot.nodeTypetag[0].nodeValue
(5)获得子标签的属性值:username = tag[0].getAttribute("username")
(6)获得标签的子标签:childs = tag.childNodes

三、使用ElementTree(元素树)解析xml(推荐)

ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
1、解析
(1)导入解析模块:import xml.etree.ElementTree as ET
(2)加载文档:tree = ET.ElementTree(file='test.xml')
(3)获取根元素:root = tree.getroot()
2、遍历
(1)循环遍历

for child in root:
    print(child.tag,":", child.attrib) 
    for children in child:
        print(children.tag, ":", children.attrib)

(2)通过下标直接访问

data = root[0][0].text

(3)使用ElementTree提供的方法

  • node = root.find(tag) 查找第一个匹配的root的子元素
  • nodes = root.findall(tag) 查找所有匹配的root的子元素
  • content = root.findtext(match,default=None) 得到第一个配置的match的元素的内容
  • nodes = root.iter(tag) 以当前元素为根节点创建树迭代器,以tag进行过滤

3、修改
(1)属性

  • attrib[] 包含元素属性的字典
  • keys() 返回元素属性名称列表
  • items()返回(name,value)列表
  • get(key, default=None) 获取属性
  • set(key, value) 跟新、添加属性
  • del xxx.attrib[key] 删除对应的属性

(2)节点

  • root.remove("test") 删除root的子节点
  • elem1 = ET.Element("test") 创建子节点
  • root.append(elem1) 添加到root的子节点
  • elem2 = ET.SubElement(root, "test_subelement") 创建添加root的子节点
  • root.extend([elem3, elem4]) 给root添加多个子节点(elem3和elem4已创建,同elem1)
  • root.insert(5, elem5) 给root在索引位置为5的地方创建子节点elem5

tree.write()保存修改后的内容

写过的脚本

1、将文件夹名以前缀的方式添加到文件名前面

import os

path = 'test'

for foldername in os.listdir(path):
    folderpath = os.path.join(path,foldername)
    for filename in os.listdir(folderpath):
        filename_path = os.path.join(folderpath,filename)
        filename2 = str(foldername) + '_' + filename
        filename_new_path = os.path.join(folderpath,filename2)
        os.rename(filename_path,filename_new_path)
        print("文件%s名称已修改" % (filename))

2、清除不含有object标签的xml文件及其对应的图片文件以及没有xml的图片

import os
import xml.etree.ElementTree as ET

path = 'end'

for dir in os.listdir(path):
	xmls = []
	print('当前文件夹:%s' %(dir))
	for file in os.listdir(os.path.join(path,dir)):
		if file.lower().endswith('xml'):
			xmls.append(file)
			new_path = os.path.join(path, dir, file)
			img_path = new_path[:-3] + 'jpg'
			tree = ET.parse(new_path)
			root = tree.getroot()
			if not root.findall('object'):
				os.remove(new_path)
				os.remove(img_path)
				print ('被删除的文件: %s,%s' %(file,file.replace('xml','jpg')))
	for file in os.listdir(os.path.join(path,dir)):
		if file.lower().endswith('jpg'):
			if file.replace('jpg','xml') not in xmls:
				new_path = os.path.join(path, dir, file)
				os.remove(new_path)
				print ('被删除的文件:%s' %(file))  

3、将超过100的图片以及xml删去

import os

path = 'image'

def removeimg(path,dirname,imgfiles,xmlfiles):
    for imgfile in imgfiles:
        if (imgfile.replace('jpg','xml')) not in xmlfiles:
            os.remove(os.path.join(path,dirname,imgfile))
            imgfiles.remove(imgfile)
    for xmlfile in xmlfiles:
        if(xmlfile.replace('xml','jpg')) not in imgfiles:
            os.remove(os.path.join(path,dirname,xmlfile))
            xmlfiles.remove(xmlfile)

for dirpath ,dirnames, filenames in os.walk(path):
    for dirname in dirnames:
        for dirpath2, dirnames2, filenames2 in os.walk(os.path.join(path,dirname)):
            imgfiles = []
            xmlfiles = []
            for filename in filenames2:
                if filename[-3:] == 'jpg':
                    imgfiles.append(filename)
                if filename[-3:] == 'xml':
                    xmlfiles.append(filename)
            if len(xmlfiles) < 100:
                print ('文件夹:%s,未标记到100张,差%d张未标记' %(dirname,100-len(xmlfiles)))
            elif len(xmlfiles) > 100:
                g = 0
                removeimg(path,dirname,imgfiles, xmlfiles)
                for i in range(len(imgfiles)):
                    if i >= 100:
                        os.remove(os.path.join(path, dirname, imgfiles[i]))
                for j in range(len(xmlfiles)):
                    if j >= 100:
                        os.remove(os.path.join(path, dirname, xmlfiles[j]))
                        g += 1
                print("文件夹:%s,当前完成标记%d张,删除多出的标记%d张" % (dirname, len(xmlfiles),g))
            else:
                removeimg(path,dirname,imgfiles,xmlfiles)
                print("文件夹:%s,当前完成标记%d张" % (dirname, len(xmlfiles)))

4、将文件夹1与文件夹2中不同的文件移出到另一个文件夹

import os,shutil

path1 = "test1"
path2 = "test"
save_path = "save"

imgs1 = []
imgs2 = []

for file in os.listdir(path1):
    imgs1.append(file)

for file in os.listdir(path2):
    imgs2.append(file)

for img1 in imgs1:
    if img1 not in imgs2:
        print(img1)
        shutil.copy(os.path.join(path1,img1),save_path)

5、统计文件夹下所有xml文件的object标签的数量

import os
import xml.etree.ElementTree as ET

path = 'test1'
num = 0

for file in os.listdir(path):
    obj = []
    if file.lower().endswith('xml'):
        xml_path = os.path.join(path,file)
        tree = ET.parse(xml_path)
        root = tree.getroot()
        for i in  root.iter('object'):
            obj.append(i)
    num = num + len(obj)
print('Number of annotated boxes:%d' % (num))

6、将文件夹中的文件按相同数量剪切到多个文件夹剪切

import os
import math
import shutil


path = 'test'
folder_path = "cut_folder"
cutnumber = 4
filenumber = 0

for file in os.listdir(path):
    filenumber += 1

foldernumber = math.ceil(float(filenumber)/cutnumber)

for i in range(foldernumber):
    j = 0
    save_path = path + "_" + str(i)
    save_path = os.path.join(folder_path,save_path)
    for file in os.listdir(path):
        file_path = os.path.join(path,file)
        if j < cutnumber:
            if not os.path.exists(save_path):
                os.mkdir(save_path)
            j += 1
            shutil.move(file_path, save_path)
            print("将文件:%s,剪切到目录%s" % (file, save_path))
        else:
            break

7、将与xml文件不对应的图片文件修改名称后移到另一个文件夹

import os
import shutil

path = "test"
save_path = "save"

imgfiles = []
xmlfiles = []

def imgmove(imgfiles,xmlfiles,dir_path,dir):
    for imgfile in imgfiles:
        if imgfile.replace('jpg', 'xml') not in xmlfiles:
            imgfile_path = os.path.join(dir_path,imgfile)
            imgfile_new = str(dir) + "_" + imgfile
            imgfile_new_path = os.path.join(dir_path,imgfile_new)
            os.rename(imgfile_path,imgfile_new_path)
            shutil.move(imgfile_new_path, save_path)
            print("将文件:%s,剪切到目录%s" % (imgfile_new, save_path))

def append(file):
    if file.lower().endswith('jpg'):
        imgfiles.append(file)
    if file.lower().endswith('xml'):
        xmlfiles.append(file)

for dir1 in os.listdir(path):
    for dir2 in os.listdir(os.path.join(path,dir1)):
        for dir3 in os.listdir(os.path.join(path,dir1,dir2)):
            imgfiles = []
            xmlfiles = []
            for file in os.listdir(os.path.join(path,dir1,dir2,dir3)):
                append(file)
            dir_path = os.path.join(path,dir1,dir2,dir3)
            imgmove(imgfiles,xmlfiles,dir_path,dir3)

8、将txt文本中记录的错误文件剪切出去

import os
import shutil

text_path = 'errorText'
save_path = 'errorImgAndXml'
folder_dir = 'basicData'

def imgAndXmlCut(errorname):
    errorname = errorname.strip()
    errorname = errorname[::-1]
    j = 0
    for i in errorname:
        j += 1
        if i == '_':
            break
    errorname = errorname[::-1]
    if not os.path.exists(save_path):
        os.mkdir(save_path)
    for folder_names in os.listdir(folder_dir):
        folder_path = os.path.join(folder_dir, folder_names)
        for file_name in os.listdir(folder_path):
            file_path = os.path.join(folder_path,file_name)
            if file_name[:-4] == errorname[:-j]:
                print("将文件:%s,剪切到目录%s" %(file_name,save_path))
                shutil.move(file_path, save_path)

def judgeError(errorname):
    file_names = []
    for file_name in os.listdir(save_path):
        file_names.append(file_name[:-4])
    errorname = errorname.strip()
    errorname = errorname[::-1]
    j = 0
    for i in errorname:
        j += 1
        if i == '_':
            break
    errorname = errorname[::-1]
    if errorname[:-j] not in file_names:
        print("此图片未找到其对应文件:%s" % (errorname),end='')

for filename in os.listdir(text_path):
    text = os.path.join(text_path, filename)
    errorinfo = open(text)
    line = errorinfo.readline()
    while line:
        imgAndXmlCut(line)
        judgeError(line)
        line = errorinfo.readline()

9、将图片以文件夹名为前缀后,剪切出去

import os
import shutil

path = "test"
save_path = "save"

for dir1 in os.listdir(path):
    for dir2 in os.listdir(os.path.join(path,dir1)):
        for dir3 in os.listdir(os.path.join(path,dir1,dir2)):
            for file in os.listdir(os.path.join(path,dir1,dir2,dir3)):
                if file.lower().endswith('jpg'):
                    file_path = os.path.join(path,dir1,dir2,dir3,file)
                    file_new = str(dir3) + "_" + file
                    file_new_path = os.path.join(path,dir1,dir2,dir3, file_new)
                    os.rename(file_path, file_new_path)
                    shutil.move(file_new_path, save_path)

10、修改xml中的标签

import os
import xml.etree.ElementTree as ET

path = "test"
alter_path = "file"
old_lable1 = "ning"
old_lable2 = "meng"
new_lable = "ningmeng"

if not os.path.exists(alter_path):
    os.mkdir(alter_path)

def alterXmlLable(file,old_lable1,old_lable2,newlable):
    xml_path = os.path.join(path,file)
    tree = ET.parse(xml_path)
    root = tree.getroot()
    for name in root.iter('name'):
        if name.text == old_lable1 or name.text == old_lable2:
            print("文件:%s中的标签值%s已被修改为%s" % (file, name.text, new_lable,))
            name.text = newlable
    tree.write(os.path.join(alter_path,file),encoding="utf-8", xml_declaration=True)


for file in os.listdir(path):
    if file.lower().endswith('xml'):
        alterXmlLable(file,old_lable1,old_lable2,new_lable)

11、删除txt只有两行的文本及其对应的图片

import os

path = "test"

for file in os.listdir(path):
    if file.lower().endswith('txt'):
        file_path = os.path.join(path,file)
        img = file.replace('txt','jpg')
        img_path = os.path.join(path,img)
        f = open(file_path)
        line = f.readlines()
        if len(line) == 2:
            f.close()
            print("%s被删除了" % (file))
            print("%s被删除了" % (img))
            os.remove(file_path)
            os.remove(img_path)

12、修改txt中的文本

import os
import io

path = "test"

def alter(file,old_str,new_str):
    file_data = ""
    with io.open(file, "r", encoding="utf-8") as f:
    	for line in f:
    		if old_str in line:
    			line = line.replace(old_str,new_str)
    		file_data += line
    with io.open(file,"w",encoding="utf-8") as f:
    	f.write(file_data)

for file in os.listdir(path):
    if file.lower().endswith('txt'):
        file_path = os.path.join(path,file)
        print(file_path)
        alter(file_path,'A','A_')

13、将文件夹中的文件按名称分到各个子文件夹

import os
import shutil

path = 'test'
save_path = 'save'
j = 8

folderName = []

if not os.path.exists(save_path):
	os.mkdir(save_path)

for folder in os.listdir(save_path):
	folderName.append(folder)
  
for file in os.listdir(path):
	file_path = os.path.join(path,file)
	if file[0:j] not in folderName:
		file_save_path = os.path.join(save_path,file[0:j])
		os.mkdir(file_save_path)
		folderName.append(file[0:j])

for file in os.listdir(path):
	for folder in os.listdir(save_path):
		if file[0:j] == folder:
			print(file)
			file_path = os.path.join(path,file)
			folder_path = os.path.join(save_path,folder)
			shutil.copy(file_path,folder_path)

14、统计txt文本中point的字符串的数量

import os

path = 'end'

for dir in os.listdir(path):
	num = 0
	file_num = 0
	for file in os.listdir(os.path.join(path,dir)):
	    point = 0
	    if file.lower().endswith('txt'):
	    	file_num += 1
	        txt_path = os.path.join(path,dir,file)
	        content = open(txt_path)
    		lines = content.readlines()
    		for str in lines:
    			if 'point' in str:
    				point = point + 1 
	    num = num + point
	print("当前文件夹 : %s" %(dir))
	print('标记的文件数量:%d' % (file_num))
	print('标记的点的数量:%d' % (num))

15、将图片从多个文件夹复制到一个文件夹

import os
import shutil

path = "image"
save_path = "save"

if not os.path.exists(save_path):
    os.mkdir(save_path)

for dir1 in os.listdir(path):
    for file in os.listdir(os.path.join(path,dir1)):
        if file.lower().endswith('jpg') or file.lower().endswith('png'):
            file_path = os.path.join(path,dir1,file)
            file_new = str(dir1) + "_" + file
            file_new_path = os.path.join(path,dir1, file_new)
            os.rename(file_path, file_new_path)
            print(file_new_path)
            shutil.copy(file_new_path, save_path)

你可能感兴趣的:(Python)