Python:os

1、os.walk

学习自:python中os.walk的用法详解 - 马里亚纳仰望星空 - 博客园

说明

遍历某个文件夹下的所有文件(包括子文件夹中)

用法

os.walk( top , topdown=True , onerror=None , followlinks=False)

参数

参数 说明
top 遍历目录的URL
topdown

True:优先遍历top目录

False:优先遍历top的子目录

onerror 一个callable对象,当walk异常时会调用
followlinks True:遍历目录下的快捷方式实际指向的目录

返回值

返回对象为一个三元组(root,dirs,files):

root:当前正在遍历的这个文件夹本身的URL

dirs:一个List,内容是该文件夹中所有目录(不包括子目录)

file:一个List,内容是该文件夹中的所有文件(不包含子目录中的文件)

如果topdown为True,walk会遍历top文件夹,与top文件夹中每一个子目录。

具体用法

原理:深度优先遍历

如果文件为如下结构

a   ->   b     ->  1.txt , 2.txt
         c     ->  3.txt
         d     ->4.txt
         5.txt
复制代码
for root,dirs,files in os.walk('a'):
    #第一次运行,当前目录为a
    root == 'a'
    dirs == [ 'b' , 'c' , 'd' ]
    files == [ '4.txt' , '5.txt' ]
    ……

    #接着遍历dirs中的每一个目录
    #先是b
    b :  root == 'a\\b'
          dirs ==  []
          files ==  [ '1.txt' , '2.txt' ]
    #dirs为空,返回(此处可以看出是深度优先遍历)

    #c
    c : root == 'a\\c'
         dirs == []
         files == [ '3.txt' ]

    #如果想要获得文件的全路径,只需要
    for f in files :
        path = os.path.join( root , f )

    #d
    d : root = 'a\\d'
         dirs == []
         files == []
    #遍历完毕,退出循环
复制代码

例1:批量处理一个文件夹中的所有文件

Q1:保持目录a的目录结构,在b中创建对应的文件夹,并把a中所有的文件加上后缀_bak

A:

复制代码
import os 

Root = 'a'
Dest = 'b'

for root,dirs,files in os.walk(Root): 
    new_root = root.replace(Root , Dest , 1)
    if not os.path.exists(new_root):
        os.mkdir(new_root)
    
    for d in dirs :
        d=os.path.join(new_root , d)
        if not os.path.exists(d):
            os.mkdir(d)

    for f in files :
        #把文件名分解为 文件名.扩展名
        # 这里可以添加一个filter , 过滤掉不想复制的文件类型,或者文件名
        ( shotname , extension ) = os.path.splitext(f)
        #原文件的路径
        old_path= os.path.join(root , f)
        new_name = shotname+'_bak'+extension
        #新文件的路径
        new_path=os.path.join(new_root , new_name)
        with open(new_path,'wb') as f:
            f.write( open(old_path , 'rb').read() )
复制代码

上文解释说明:

1、

for root,dirs,files in os.walk(Root):  ①
    new_root = root.replace(Root , Dest , 1) ②
    if not os.path.exists(new_root): ③
        os.mkdir(new_root)

①:遍历访问Root目录下的文件、目录

②:把路径Root中的a替换为b,替换次数为一次,得到新路径new_root

③:如果new_root路径不存在,那就生成该路径代表的目录

2、

    for d in dirs : ①
        d=os.path.join(new_root , d)
        if not os.path.exists(d):②
            os.mkdir(d)

①:对Root下所有子目录,更换新路径为 new_root/d,即'b/子目录'(以前是a/子目录)

②:如果该新路径代表的目录不存在,就用os.mkdir(d)生成

3、

复制代码
for f in files :
        #把文件名分解为 文件名.扩展名  ***
        # 这里可以添加一个filter , 过滤掉不想复制的文件类型,或者文件名
        ( shotname , extension ) = os.path.splitext(f) ①
        #原文件的路径
        old_path= os.path.join(root , f) ②
        new_name = shotname+'_bak'+extension ③
        #新文件的路径
        new_path=os.path.join(new_root , new_name) ④
        with open(new_path,'wb') as f: ⑤
            f.write( open(old_path , 'rb').read() )
复制代码

对该目录下的所有文件

①:分解为文件名+后缀名的形式( shotname , extension )

②:root+filename得到老文件的路径

③:字符串拼接“+”的方式得到新文件名

(filename , extension) = os.path.splitext( f )

new_name = filename + '_bak' + extension

这种写法值得借鉴

④:新路径与新文件名用join连接得到新路径下的文件名

⑤:文件复制,方法:将老文件中的内容以读取的方式打开读出,再写入新文件中

with open(new_path , 'wb') as f :
        f.write( open(old_path,'rb').read() )

补充:***处的过滤方式为,字符串的筛选方式

例2:循环访问并处理某个文件夹中的所有文件

#假设该文件夹为的绝对路径为D://Python

rootdir='D://Python'
for root, dirs, files in os.walk(rootdir):#遍历整个文件夹
     for file in files:
          filedir = os.path.join(root,file)  #得到文件的绝对路径 也可以用 root + '\\' +file
          func(filedir) #用func函数处理每个文件

2、os.path

参考文档:Python os.path() 模块 | 菜鸟教程

该模块主要用于获取文件属性

方法

返回值

说明

os.path.abspath(path)   返回绝对路径
os.path.basename(path)   返回文件名
os.path.commonprefix(list)   返回list中,所有path共有的最长路径
os.path.dirname(path)   返回相对路径(从程序所在目录开始)
os.path.exists(path)   如果路径(相对/绝对)path存在,返回True;path不存在,返回False
os.path.expanduser(path)   把path中包含的"~"与"~user"转换为用户目录
os.path.expandvars(path)   根据环境变量的值替换path中包含的“$name”与“${name}”
os.path.getatime(path)   返回最近访问时间(浮点型秒数)
os.path.getmtime(path) float,时间戳 返回文件的最近修改时间
os.path.getctime(path) 返回文件path创建时间
os.path.getsize(path) 返回文件大小,不存在就返回错误
os.path.isabs(path)   判断路径是否为绝对路径
os.path.isfile(path)   判断路径是否为文件
os.path.isdir(path)   判断路径是否为目录
os.path.islink(path)   判断路径是否为链接
os.path.join(path1,path2,...)   将路径合并,格式为path1\\path2
os.path.normcase(path)   转换path的大小写和斜杠(一个斜杠转两个斜杠、三变四、……)
os.path.normpath(path)   规范path的字符串形式
os.path.realpath(path)   返回path的真实路径
os.path.relpath(path [, start])   从start开始计算相对路径
os.path.samefile(path1,path2)   判断目录或者文件是否相同
os.path.split(path)   将路径分割为dirname和basename,返回一个元组(路径,文件名)
os.path.splitext(path)   将路径分割为文件名和扩展名的元组(文件名, 扩展名(如.txt,.py,...))

注意:

  1. os.path.join()连接时,第二个路径不能以\开头,否则会导致前一个路径被截断到第一个\

3、其他os方法

方法 说明
os.access(path , mode) 检查文件权限模式
os.chdir(path) 改变当前工作目录
os.fchdir(fd) 通过文件描述符fd改变当前工作目录
os.chflags(path , flags) 设置路径的标记为数字标记
os.chmod(path , mode) 更改权限
os.fchmod(fd , mode) 改变一个文件的访问权限,该文件由fd指定,参数mode是Unix下的文件访问权限
os.chown(path,uid,gid) 更改文件所有者,uid为用户id,gid为用户组id
os.fchown(fd, uid ,gid) 修改文件描述符fd指定的文件的所有者
os.close(fd) 关闭文件描述符fd
os.closerange(fd_low , fd_high) 关闭所有文件描述符,从fd_low(包含)到fd_high(不包含)。错误会忽略
os.dup(fd) 复制文件描述符fd
os.dup2(fd , fd2) 将一个文件描述符fd复制到另一个fd2
os.ftruncate(fd,length) 裁剪fd指定的文件,length不能超过文件大小
os.getcwd() 返回当前工作目录的路径
os.listdir(path) 返回path指定的文件夹包含的文件或文件夹名字的List
os.mkdir(path[,mode]) 以数字mode的mode创建一个名为path的文件夹,默认的mode是0777(八进制)
os.remove(path) 删除路径为path的文件。如果是文件夹,将抛出OSError。删除文件夹用os.removedirs
os.removedirs(path) 删除目录和目录下的所有文件
os.rename(src , dst) 重命名文件或目录,原名src修改为新名dst
os.renames(old , new) 递归地对目录进行更名,也可以对文件进行更名

4、例子

1)getcwd:获取当前路径

os.getcwd()

2)listdir:列出某个路径下的所有文件和文件夹

os.listdir(os.getcwd())

3)获取文件的修改时间,转为datetime类型

1
2
from datetime import datetime as dt
mtime=dt.fromtimestamp(os.path.getmtime('a.txt'))<br>#进一步判断该时间与2023.1.1这个时间差了几天<br>is2023=(mtime-dt(2023,1,1).days)

4)区分文件名和扩展名

(filename , extension) = os.path.splitext( f )

5、问题

1)os.walk时直接返回,并没有正常进行下去

路径中有转义字符,此时需要用双斜杠//

posted @   ShineLe  阅读(141)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示