【python办公自动化】有趣的小发现,在多文件夹路径下的原位置重命名文件

在多文件夹路径下的原位置重命名文件

手动反爬虫:原博地址

 知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息

如若转载,请标明出处,谢谢!

1. 背景

故事的情景是这样发生的,今天需要装一个地图可视化的包cartopy,为了保证cartopy的精致小巧,该包并未附带任何地理数据,默认下载后是没有预装各种版本的地图文件的,因此就在网上下载了对应的地理数据,解压之后发现所有的文件名称和官方的数据对比都是少了“ne_”,数据有涉及到了两个文件夹,总共有81个文件,说实话这时候要是不会办公自动化就直接手动修改就好了,可是学过了就习惯的把之前已经编好的代码复制粘贴过来了,然后就发现有意思的东西出来
在这里插入图片描述
如下是cultural中的文件,需要将所有的文件前面都加上“ne_”的前缀
在这里插入图片描述
把之前【python办公自动化(3)】中的代码copy过来了,然后直接执行

import os
os.chdir(r'C:\Users\86177\Desktop\测试文件')
print(os.getcwd())

for dirpath,dirnames,files in os.walk('./'):
    #print(dirpath)
    for file in os.scandir(dirpath):
    	if file.is_file():
    		# print(file.name)
    		os.rename(file, 'ne_' + file.name)

输出结果为:(和【python办公自动化(3)】中解析的一样,代码执行后修改的名称的文件会全部在os.getcwd()所对应的文件夹下,由于这里存在两个文件夹,所有这样输出的话,不知道这些文件该如何归类到其原来对应的文件夹中了)
在这里插入图片描述
因此就需要获取文件夹的名称,然后将重命名的文件转移到对应的文件夹中,代码如下

import os
os.chdir(r'C:\Users\86177\Desktop\测试文件')
print(os.getcwd())

for dirpath,dirnames,files in os.walk('./'):
    #print(dirpath)
    for file in os.scandir(dirpath):
    	if file.is_file():
    		# print(file.name)
    		# print(dirpath + '/' + 'ne_' + file.name)
    		# print(dirpath + '/' + file.name)
    		# os.rename(file, dirpath + '/' + 'ne_' + file.name) 这种和下面一种是一样的结果
    		os.rename(dirpath + '/' + file.name, dirpath + '/' + 'ne_' + file.name)

输出结果为:(这时候发现报错了,就很奇怪,而且会出现这么多的“ne_”的前缀,这时候就的想办法进行就解决问题了,找一下问题出在了哪里)
在这里插入图片描述

2. 尝试探索

于是就在桌面创建一个测试文件夹,为了防止数据被破坏,再创建测试的内容之后进行文件压缩,方便多次实践,于是就在桌面创建的内容如下,该测试文件夹下有a1和b1两个子文件,各子文件中有四个文件
在这里插入图片描述
然后执行刚刚的代码,不需要修改任何地方,直接运行

import os
os.chdir(r'C:\Users\86177\Desktop\测试文件')
print(os.getcwd())


for dirpath,dirnames,files in os.walk('./'):
    #print(dirpath)
    for file in os.scandir(dirpath):
    	if file.is_file():
    		# print(file.name)
    		# print(dirpath + '/' + 'ne_' + file.name)
    		# print(dirpath + '/' + file.name)
    		# os.rename(file, dirpath + '/' + 'ne_' + file.name)
    		os.rename(dirpath + '/' + file.name, dirpath + '/' + 'ne_' + file.name)

输出结果为:(可以发现能正常修改文件的前缀,那么为什么之前文件为什么不可以?还出现那么多的前缀,最后对比差异发现测试内容唯一的不同就是文件的数量多少了)
在这里插入图片描述
于是进行文件数量的添加,把b1中的文件复制放在a1中,a1的文件赋值放在b1中,这样每个子文件夹中就有8个文件了,然后再继续测试,这次为了证明代码中的两行os.rename()语句功能等价,这里使用第一行的代码

import os
os.chdir(r'C:\Users\86177\Desktop\测试文件')
print(os.getcwd())

for dirpath,dirnames,files in os.walk('./'):
    #print(dirpath)
    for file in os.scandir(dirpath):
    	if file.is_file():
    		# print(file.name)
    		# print(dirpath + '/' + 'ne_' + file.name)
    		# print(dirpath + '/' + file.name)
    		os.rename(file, dirpath + '/' + 'ne_' + file.name)
    		# os.rename(dirpath + '/' + file.name, dirpath + '/' + 'ne_' + file.name)

输出结果为:(这次还是正常输出,注意上面最后两行的代码,file是一个类数据,file.name是字符串数据,但是两行代码的功能是一致的)
在这里插入图片描述
由此可以发现8条数据也不会影响程序的执行,之后就继续进行加数据,测试了10条,之后每次+5条,15条,20条,都是正常输出,直至数据加到25条时候,程序报错,说明确实是数据量的多少导致程序的崩溃,那么具体我的电脑可以处理多少条不报错了(每个人的电脑处理性能不同,这个数字可能有差异),就在20-25之间一条一条的测试,最后发现结果如下:

当选择的数据量为22条时候,可以正常重命名文件的
在这里插入图片描述
当选取数据量为23条时候,熟悉的场景又回来了,也就是说我的计算机使用这种方法最大的处理文件的数量为22,超过这个数值后就报错了
在这里插入图片描述
至此问题也就明确了,的确是数据量超过了一定数量导致了程序报错,那么原理是啥呢?根本原因就是在原位置进行文件的重命名,那么重命名的过程需要一定的时间,而且重命名的文件还是会在遍历循环的文件夹中,如果遍历循环的过程中把之前的重命名的文件也遍历了,那么就出现了前面很多“ne_”的情况,也就是超过最大处理的22个文件的时间期限,重命名的文件会再次被遍历从而再次被改名

3. 问题解决

问题出现的根本原因就是使用的遍历循环是在重命名的文件夹中,如果文件的数量较多的时候,就会出现一直进行数据添加循环重命名的现象,所以解决问题的方式有两种,第一种就是把重命名的文件移动到文件夹外面,然后再遍历结束后重新转移到原文件夹中(这一种显示是多出来了一个中间步骤),第二种就是直接读取要修改文件里面的所有的文件名称后,然后直接进行文件的重命名(相当于阻止了重命名的文件再次被遍历),所以从简洁性上来看选择第二种方式较好,因此就需要有文件中的所有的文件全部读取,这时候就可以用到glob库,代码如下

import os
os.chdir(r'C:\Users\86177\Desktop\测试文件')
print(os.getcwd())
import glob

paths = glob.glob('**/*', recursive = True)

for path in paths:
	if '.' in path:
		basename = os.path.basename(path)
		dirname = os.path.dirname(path)
		# print(parent_name)
		# print(basename)
		print(path)
		os.rename('./' + path,'./' + dirname + './'+ 'ne_' + basename)

输出的结果:(比如在physical文件夹中有54个文件,直接就完成重命名了)
在这里插入图片描述
cultural文件夹中有27个文件,也正常添加了前缀
在这里插入图片描述
至此整个在多文件夹路径下的原位置重命名文件的梳理就完结了,最后的要点在于获取文件的名称和文件的目录,方便重命名的文件的移动,之前方法的有意义的地方也是之前忽视的地方,在原位置下重命名文件后会留在原文件夹中,这样就有点类似永动机的意味了,只要处理文件的时间大于遍历的时间,就会到重命名的文件源源不断的加入到循环的文件夹中,导致程序崩溃。

猜你喜欢

转载自blog.csdn.net/lys_828/article/details/107843255