栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python路径、文件夹、文件常见操作

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python路径、文件夹、文件常见操作

文章目录
  • 1. os.walk(遍历多层文件夹)
    • 1.1 一般用法
    • 1.2 访问特定层级/深度的文件夹
    • 1.3 排除os.walk中部分文件夹的迭代
    • 1.4 统计多层文件结构的文件/文件夹数量
  • 2. os.listdir
  • 3. pathlib.Path.glob
  • 4. 判断一个文件是普通文件还是文件夹
  • 5. 重命名,移动/复制文件
    • 5.1 os.rename
    • 5.2 shutil.move
    • 5.3 shutil.copy

1. os.walk(遍历多层文件夹) 1.1 一般用法

我现在有以下文件夹结构,为了处理.dcm文件,需要在LCTSC-Test-S1-101文件的基础上,访问到存储.dcm文件所在的文件夹。

~/Downloads/LCTSC/LCTSC-Test-S1-101 » tree -L 3
.
└── 03-03-2004-NA-NA-08186
    ├── 1.000000-NA-56597
    │   └── 1-1.dcm
    └── NA-79262
        ├── 1-001.dcm
        ├── 1-002.dcm

因此考虑使用os.walk,示例如下:

for root, dirs, files in os.walk(nii_name_path[0], topdown=True):
    for name in files[:3]:  # 打印文件
        print(os.path.join(root, name))
    for name in dirs:  # 打印所有目录/文件夹
        print(os.path.join(root, name))

# 结果如下        
> ../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/1.000000-.simplified-23857
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/211.000000-Ave-IP10 0102030405060708090-83140
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/1.000000-.simplified-23857/1-1.dcm
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/211.000000-Ave-IP10 0102030405060708090-83140/21-008.dcm
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/211.000000-Ave-IP10 0102030405060708090-83140/13-002.dcm
../LCTSC/LCTSC-Train-S2-008/01-09-1999-NA-4DCT THORAX-15057/211.000000-Ave-IP10 0102030405060708090-83140/03-002.dcm

参考:

  • 菜鸟教程:Python os.walk() 方法
  • GeeksforGeeks:os.walk() in Python
  • Stack Overflow:A Faster way of Directory walking instead of os.listdir?,这个问题是讨论os.walk等的运行效率的
1.2 访问特定层级/深度的文件夹

根据参考内容进行整理,没有特别高档的方法,都是walk的结果进行一些简单的判断,让它不至于输出。

解决1

来自Github wiki:A python function to do an os.walk(), but only to a certain depth. A negative depth indicates full depth.

import os

def walklevel(path, depth = 1):
    """It works just like os.walk, but you can pass it a level parameter
       that indicates how deep the recursion will go.
       If depth is 1, the current directory is listed.
       If depth is 0, nothing is returned.
       If depth is -1 (or less than 0), the full depth is walked.
    """
    if depth < 0:
        for root, dirs, files in os.walk(path):
            yield root, dirs[:], files
        return
    elif depth == 0:
        return
        
    base_depth = path.rstrip(os.path.sep).count(os.path.sep)
    for root, dirs, files in os.walk(path):
        yield root, dirs[:], files
        cur_depth = root.count(os.path.sep)
        if base_depth + depth <= cur_depth:
            del dirs[:]

解决2
来自Stack Overflow:os.walk without digging into directories below

import os

def walklevel(some_dir, level=1):
    some_dir = some_dir.rstrip(os.path.sep)
    assert os.path.isdir(some_dir)
    num_sep = some_dir.count(os.path.sep)
    for root, dirs, files in os.walk(some_dir):
        yield root, dirs, files
        num_sep_this = root.count(os.path.sep)
        if num_sep + level <= num_sep_this:
            del dirs[:]

参考:

  • python os.walk to certain level
1.3 排除os.walk中部分文件夹的迭代

参考Stack Overflow:Excluding directories in os.walk

只需要加一个判断即可,例如:

exclude = set(['New folder', 'Windows', 'Desktop'])
for root, dirs, files in os.walk(top, topdown=True):
    dirs[:] = [d for d in dirs if d not in exclude]
1.4 统计多层文件结构的文件/文件夹数量
import os
base_dir="XXX"

all_files=[]
all_dir=[]
for root, dirs, files in os.walk(base_dir, topdown=True):
    for name in dirs:
        all_dir.append(os.path.join(root, name))
    for name in files:
        if "DS_Store" not in name:  # 如果是mac,排除.DS_Store文件问题
            all_files.append(os.path.join(root, name))
print(len(all_dir))
print(len(all_files))  
2. os.listdir
import os
base_dir="XXX"
file_list=os.listdir(base_dir)

3. pathlib.Path.glob

根据Stack Overflow:How to use glob() to find files recursively?

例如,我想找到一个文件夹中所有以LCTSC开头的文件夹,文件结构如下:

~/Downloads/LCTSC » tree -L 1                 
.
├── LCTSC-Test-S1-101
├── LCTSC-Test-S1-102
├── LCTSC-Test-S1-103
├── LCTSC-Test-S1-104
├── LCTSC-Test-S1-201
├── LCTSC-Test-S1-202
├── ...
└── LICENSE

可以:

import glob
nii_name_path=glob.glob('../LCTSC/LCTSC*')

glob函数不像listdir一样,有一个单独的路径参数,它只接受一个参数,在指定base_dir的同时就要写好筛选文件的正则表达式,如上。

参考:

  • CSDN博客:python os.path glob.glob函数
  • python官方文档:glob — Unix style pathname pattern expansion
4. 判断一个文件是普通文件还是文件夹
  • os.path.exists(path),判断这个路径是否正确,这个路径可以是一个文件夹/文件或者软连接(快捷方式)等
  • os.path.isfile(path),如果路径是一个普通文件或者指向一个文件的链接,则返回true
  • os.path.isdir(path),如果路径是一个文件夹或者指向文件夹的链接,则返回true

例如:

import os.path

if os.path.isfile('filename.txt'):
    print ("File exist")
else:
    print ("File not exist")

参考:

  • How to Check if a File or Directory Exists in Python
5. 重命名,移动/复制文件 5.1 os.rename

示例

os.rename("../a/123.txt","../b/12.txt")

语法
将src参数所代表的文件或者目录重命名为dst,如果dst已经存在,会抛出一个OSError子类的错误,执行失败。

  • 在Windows平台上,如果dst存在,则总是会抛出FileExistsError
  • 在Unix上,
    • 如果scr是一个文件,dst是一个目录(反之也可以),则会分别抛出一个IsADirectoryError或NotADirectoryError错误。
    • 如果两个都是目录,dst为空,则dst会被静默替换;如果dst一个非空的目录,则会抛出OSError错误.
    • 如果两个都是文件,如果用户具有权限,则dst将会被静默替换。如果 src 和 dst 在不同的文件系统上,该操作可能会在某些 Unix上失败。 如果成功,重命名将是一个原子操作(这是 POSIX 要求)。
  • 此函数可以支持指定 src_dir_fd 和 dst_dir_fd 以提供相对于目录描述符的路径。

文件夹内操作相当于直接重命名,跨文件夹操作相当于移动文件并重命名(没有复制,直接移动)

参考:

  • 菜鸟教程:Python os.rename() 方法
  • python官方文档:os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
  • 博客园文章:【原创】Python rename用法
5.2 shutil.move

示例

import shutil
shutil.move('file.txt', 'path/to/new/directory/')

语法解释

shutil.move(src, dst, copy_function=copy2)
  • 迭代的将一个文件或者目录(scr参数)移动到另一个地址(dst参数),返回dst
  • 如果dst是一个已有的目录,则src会直接移动到这个目录中。
  • 如果dst已经存在但不是一个目录,其会根据os.rename()的语法来决定是否覆盖
  • 如果dst位于当前的文件系统中,则直接使用os.rename()(即src和dst在同一目录中)。
    • 否则在其他情况时,src会使用copy_function复制到dst,然后被删除。
    • 如果是软链接,则会有一个指向src代表的目标的新链接被创建,同时scr会被删除
  • copy_function是一个可以自己指定函数的参数,一般不使用

shutil.move与os.rename的区别

  • 从调用上就可以看出明显的区别。
    os.rename("../a/123.txt","../b/12.txt")
    shutil.move('file.txt', 'path/to/new/directory/')	
    
  • shutil.move的第二个参数只能是个目录
  • os.rename可以在重命名的时候捎带就移动个位置

参考:

  • Stack Overflow:Rename and move file with Python
  • os.rename vs shutil.move
  • python官方文档:shutil.move(src, dst, copy_function=copy2)
5.3 shutil.copy

shutil.copy(src, dst, *, follow_symlinks=True)

示例

import shutil
shutil.copy(oldName, newName)

os.rename("../a/123.txt","../b/12.txt")
shutil.copy("../a/123.txt","../b/12.txt")
"""
二者的区别在于,
rename是移动,src中的文件会消失
而copy是复制,scr中的文件依然会保留
"""

参考

  • python官方文档:shutil.copy(src, dst, *, follow_symlinks=True)
  • python 复制一个文件并进行重命名
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/822311.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号