Python入门之(6.2)目录的操作

目录

目录的操作

1.1 目录与文件操作函数

1.2 目录的遍历


 

目录的操作

1.1 目录与文件操作函数

文件是由操作系统来管理的,并通过文件夹的方式来管理大量的文件。文件除了读写操作以外,还可以进行复制、移动、删除等操作。文件夹也可以进行创建、移动、获取文件等操作。Python中对文件、文件夹操作时,可以使用os模块或shutil模块,如下面的两个表格所示:

os模块中常用的方法
方法功能描述
os.getcwd()得到当前工作目录,即当前Python脚本工作的目录路径
os.listdir(path)返回指定目录path下的所有文件和目录名
os.remove(filename)该方法用来删除一个文件,不能删除目录
os.removedirs(path)递归地删除多个目录,若目录没有成功删除,将抛出错误
os.rmdir(path)删除目录path,要求path必须是空目录,否则抛出OSError错误
os.path.isfile(path)检验给出的路径path是否是一个文件
os.path.isdir(path)检验给出的路径path是否是一个目录
os.path.isabs(path)判断path是否是绝对路径
os.path.exists(path)判断给出的路径path是否存在
os.path.split(path)把路径分割成路径名和文件名,返回一个元组
os.path.splitext(path)分割路径,返回路径名和文件扩展名的元组
os.path.dirname(path)返回文件的路径名
os.path.basename(path)返回文件名
os.path.getsize(path)返回文件大小,如果文件不存在,返回错误
os.rename(old,new)文件重命名
os.makedirs(path)创建多级目录
os.mkdir(path)创建单个目录
os.stat(file)获取文件属性
os.chmod(file)获取修改文件权限与时间戳
os.exit()终止当前进程
os.path.join(str1,str2)将多个路径组合后返回
shutil模块中常用的方法
方法功能描述
shutil.copyfile(src,dst)从源src复制到dst中去。要求目标地址具备可写权限,且若dst存在,则覆盖
shutil.move(src,dst)移动文件或重命名
shutil.copymode(src,dst)仅复制权限,不更改文件内容、组和用户
shutil.copystat(src,dst)复制所有的状态信息,包括权限、组、用户、时间等
shutil.copy(src,dst)复制文件的内容以及权限,先copyfile再copymode
shutil.copy2(src,dst)复制文件的内容以及文件的所有状态信息,先copyfile再copystat
shutil.copytree(src,dst)递归地复制文件内容及状态信息
shutil.rmtree(path)递归地删除文件
shutil.move(src,dst)递归地移动文件

make_archive(base_name,

format,root_dir=None,base_dir=None,

verbose=0,dry_run=0,owner=None,

group=None,logger=None)

压缩打包:

base_name:压缩打包后的文件名或路径名

format:压缩或者打包格式zip、tar、bztar或gztar

root_dir:指定将哪个目录或文件打包(也就是源文件)

shutil是一种高层次的文件操作工具,类似于高级API,其强大之处在于对文件的复制与删除操作很灵活。

编写一个Python程序,对于指定文件夹下的图片文件,按照用户给出的前缀和编码方式统一命名。

设计思路:用户输入文件后缀名和所在文件夹,查找是否存在这些文件,筛选文件夹下所有指定后缀的文件并存放到列表对象中。输出所有这些文件,询问用户是否重新命名。如果是,要求输入统一命名后的文件名前缀和数字编码位数,调用rename()方法对文件列表中的文件重命名,并输出命名结果。

程序为:

import os
#文件批量重命名函数
def imgRename():
    #输入文件名后缀strip()方法用于删除多余的空格
    ext=input('请输入要批量命名的文件后缀名:(如jpg、png等)。直接回车退出程序\n').strip()
    if ext=='':
        return      #如果按enter键,退出函数
    myPath=input('请输入图片文件所在文件夹:')
    #获得指定文件夹下的所有文件信息并存入列表对象allFiles
    allFiles=os.listdir(myPath)
    ext_list=[]        #ext_list用来存放指定后缀的文件,初值为空
    list_len=[]        #list_len用来存放文件名的长度,用于输出对齐
    for ifile in allFiles:
        #文件名和目录拼接成完整的路径
        fullFile=os.path.join(myPath,ifile)
        if os.path.isfile(fullFile) and os.path.splitext(ifile)[1][1:].lower()==ext:
            #如果是文件且后缀为指定后缀,则添加到列表中
            ext_list.append(ifile)
            #每个文件名的长度添加到列表中
            list_len.append(len(ifile))
    if len(ext_list)==0:
        print('未发现*.',ext,'类型的文件')
        return
    print('找到如下*.',ext,'文件:')
    #遍历列表对象,输出指定文件夹下匹配后缀的所有文件名
    for item in ext_list:
        print(item)
    print(25*'*')   #连续打印25个*
    choice=input('您确定要对这些文件批量重命名吗?\n(Y/y----确定,N/n----取消)')
    if choice!='y' and choice!='Y':
        return
    else:
        fi_num_cnt=1           #文件编号初始化为1
        input_max_len=max(list_len)     #获得文件名的最大长度
        preFix=input('请输入文件前缀:')   #输入数字编号之前的前缀
        #输入编号位数
        noSize=int(input('请输入编号宽度,如1表示编号为1,2,3……,3表示编号为001,002,003……'))
        #输入重新命名目标文件夹
        dstPath=input('请输入重命名后图片文件所在文件夹:')
        for ifile in ext_list:    #遍历列表,对每个文件重命名
            #生成新文件名,其中,zfill()方法用于在数字前补零
            new_name=preFix+str(fi_num_cnt).zfill(noSize)+'.'+ext
            #如果新生成的文件名已存在,则增加编号,继续生成新文件名
            while True:
                if os.path.exists(os.path.join(dstPath,new_name)):
                    fi_num_cnt+=1
                    new_name=preFix+str(fi_num_cnt).zfill(noSize)+'.'+ext
                else:
                    break
            #输出新、旧文件名信息
            print(ifile.rjust(input_max_len,' '),3*' ','重命名为:'.ljust(5,' '),new_name.rjust(10,' '))
            try:
                #调用rename()方法重新命名文件
                os.rename(os.path.join(myPath,ifile),os.path.join(dstPath,new_name))
            except Exception as e:
                print(e)
            fi_num_cnt+=1
    print('运行结束!')
if __name__=='__main__':
    imgRename()

 

运行结果为:

E:\PycharmProjects\PythonTest\venv\Scripts\python.exe E:/PycharmProjects/PythonTest/ssss.py python ssss.py 5 2
请输入要批量命名的文件后缀名:(如jpg、png等)。直接回车退出程序
jpg
请输入图片文件所在文件夹:C:\Users\Desktop\新建文件夹\汉口江滩
找到如下*. jpg 文件:
97820423A438CDEA70F63BC8F496582E.jpg
99E4EA6342F1AB16601C884EDA93094D.jpg
A9E206588A20CA06B4AA8B3AE07AE2F2.jpg
*************************
您确定要对这些文件批量重命名吗?
(Y/y----确定,N/n----取消)y
请输入文件前缀:mycat
请输入编号宽度,如1表示编号为1,2,3……,3表示编号为001,002,003……3
请输入重命名后图片文件所在文件夹:C:\Users\Desktop\新建文件夹\汉口江滩1
97820423A438CDEA70F63BC8F496582E.jpg     重命名为: mycat001.jpg
99E4EA6342F1AB16601C884EDA93094D.jpg     重命名为: mycat002.jpg
A9E206588A20CA06B4AA8B3AE07AE2F2.jpg     重命名为: mycat003.jpg
运行结束!

Process finished with exit code 0

 

1.2 目录的遍历

在文件操作中经常需要遍历某个文件夹或者子文件夹。在Python中进行文件遍历的方式很多,下面介绍几种常用的方式。

1.使用os.popen()方法运行命令

语法格式:      os.popen(command[,mode[,bufsize]])

功能:用于从一个命令打开一个管道,在Unix、Windows中有效。返回一个文件描述符号为fd的打开的文件对象。

参数说明:

  1. command  使用的系统命令
  2. mode  模式权限,可以是r(默认)或w
  3. bufsize  指明文件需要的缓冲大小:0意味着无缓冲;1意味着行缓冲;其他正值表示使用参数大小的缓冲(大概值,以字节为单位)。负的bufsize意味着使用系统的默认值。一般来说,对于tty设备,它是行缓冲;对于其他文件,它是全缓冲。如果没有改参数,使用系统的默认值。

2.使用glob模块的glob(path)方法

语法格式:      glob.glob(pathname)

功能:逐个获取匹配的文件路径名,返回所有匹配的文件路径列表

参数说明:

  1. pathname  定义了文件路径匹配规则,可以是绝对路径,也可以是相对路径
  2. 查找文件只用到3个匹配符 *、?和[]。*匹配0个或多个字符;?匹配单个字符;[]匹配指定范围内的字符

3.使用os.listdir()方法

详见上面的表格。

4.使用os.walk()方法

语法格式:    os.walk(top[,topdown=True[,οnerrοr=None[,followlinks=False]]])

功能:通过在目录树中遍历,输出在目录中的文件名,可以向上或者向下。在Unix、Windows中有效。

参数说明:

  1. top  根目录下的每一个文件夹(包含它自己),产生一个三元组(dirpath,dirnames,filenames)[文件夹路径,文件夹名字,文件名]
  2. topdown  可选,为True或者没有指定,一个目录的三元组将比它的任何子文件夹的三元组先产生(目录自上而下)。如果topdown为False,一个目录的三元组将比它的任何子文件夹的三元组后产生(目录自下而上)
  3. onerror()  可选,是一个函数;调用时需要一个参数,一个OSError实例。报告错误后,继续walk,或者抛出exception终止walk。
  4. followlinks  设置为True,则通过软链接访问目录

不同遍历方式示例的程序代码如下:

import os
import glob
def listByShell(path):
    for f in os.popen('dir '+path):
        print(f.strip())
def listByGlob(path):
    for f in glob.glob(path+'/*'):
        print(f.strip())
def listByListdir(path):
    for f in os.listdir(path):
        print(f.strip())
def listByOSWalk(path):
    for (dirname,subdir,subfile) in os.walk(path):
        print('['+dirname+']')
        for f in subfile:
            print(os.path.join(dirname,f))
def main():
    print('使用os.popen方法遍历:')
    listByShell(r'e:\PycharmProjects')
    print('使用glob,glob方法遍历:')
    listByGlob(r'e:\PycharmProjects')
    print('使用os.listdir方法遍历:')
    listByListdir(r'e:\PycharmProjects')
    print('使用os.walk方法遍历:')
    listByOSWalk(r'e:\PycharmProjects')
main()

运行结果为:

E:\PycharmProjects\PythonTest\venv\Scripts\python.exe E:/PycharmProjects/PythonTest/ssss.py python ssss.py 5 2
使用os.popen方法遍历:
驱动器 E 中的卷没有标签。
卷的序列号是 C402-DAC5

e:\PycharmProjects 的目录

2019/07/18  10:47    <DIR>          .
2019/07/18  10:47    <DIR>          ..
2019/08/20  10:57    <DIR>          PythonTest
2018/10/12  20:43    <DIR>          test
0 个文件              0 字节
4 个目录 71,039,795,200 可用字节
使用glob.glob方法遍历:
e:\PycharmProjects\PythonTest
e:\PycharmProjects\test
使用os.listdir方法遍历:
PythonTest
test
使用os.walk方法遍历:
[e:\PycharmProjects]
[e:\PycharmProjects\PythonTest]
e:\PycharmProjects\PythonTest\modu1.py
e:\PycharmProjects\PythonTest\modu2.py
e:\PycharmProjects\PythonTest\muModu.py
e:\PycharmProjects\PythonTest\sample5_17.py
e:\PycharmProjects\PythonTest\sample5_18.py
e:\PycharmProjects\PythonTest\ssss.py
[e:\PycharmProjects\PythonTest\.idea]
e:\PycharmProjects\PythonTest\.idea\misc.xml
e:\PycharmProjects\PythonTest\.idea\modules.xml
e:\PycharmProjects\PythonTest\.idea\PythonTest.iml
e:\PycharmProjects\PythonTest\.idea\workspace.xml

Process finished with exit code 0

编写程序,遍历指定目录及所有子目录,将所有子目录名和文件名全部改为小写。

设计思路:根据题目要求,需要递归遍历文件夹下的所有文件及子文件夹。可以用os.work()方法完成,这样就不需要编写递归遍历程序。对方法的返回结果进行遍历。首先遍历所有文件,修改文件名全部为小写;然后遍历所有文件夹,修改所有文件夹的名字为小写。

程序如下:

import os
import os.path
#读入指定目录并转换为绝对路径
rootdir=input('请输入文件夹:')
#先从外向内依次修改每个目录下的文件名
#利用os.work()方法读入所有的文件夹和文件夹中的文件
#遍历每个文件夹,检测该文件夹的所有文件名并重命名
for (dirname,subdir,files) in os.walk(rootdir):
    #遍历每个文件,检测该文件名是否符合要求
    for file in files:
        #文件名与目录名拼接成完整路径
        pathfile=os.path.join(dirname,file)
        #把文件名转换成小写字母
        pathfileLower=os.path.join(dirname,file.lower())
        #检测文件名是否是小写字母
        if pathfile==pathfileLower:
            continue
        #打印转换前后的文件名
        print(pathfile+'-->'+pathfileLower)
        #调用rename()方法完成重命名操作
        os.rename(pathfile,pathfileLower)
#然后,从内向外依次修改每个目录名
#参数topdown决定遍历的顺序,如果为True,从外向内;如果是False,从内向外
#以下循环结构用于由内向外遍历每个文件夹,检测该文件夹的名字并重命名
for (dirname,subdir,files) in os.walk(rootdir,topdown=False):
    #遍历每个文件夹,检测该文件夹的名字是否符合要求
    for dirs in subdir:
        #文件夹名与目录名拼接成完整路径
        pathdir=os.path.join(dirname,dirs)
        pathdirLower=os.path.join(dirname,dirs.lower())
        if pathdir==pathdirLower:
            #如果文件夹名全是小写,检测下一个文件夹名
            continue
        print(pathdir+'-->'+pathdirLower)
        #文件夹重命名
        os.rename(pathdir,pathdirLower)

运行结果为:

E:\PycharmProjects\PythonTest\venv\Scripts\python.exe E:/PycharmProjects/PythonTest/ssss.py
请输入文件夹:E:\SHI
E:\SHI\SHI_1.txt-->E:\SHI\shi_1.txt
E:\SHI\SHI_2.txt-->E:\SHI\shi_2.txt
E:\SHI\TRY\TRY_1.txt-->E:\SHI\TRY\try_1.txt
E:\SHI\TRY\TRY_2.txt-->E:\SHI\TRY\try_2.txt
E:\SHI\TRY-->E:\SHI\try

Process finished with exit code 0

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值