零基础小白必看:python基本操作-文件、目录及路径

使用python的os模块,简单方便完成对文件夹、文件及路径的管理与访问操作。

1 前言

在最近开发中,经常需要对文件进行读取、遍历、修改等操作,想要快速、简单的完成这些操作,我选择用 python 。通过 python 的标准内置 os 模块,只需要几行代码,即可完成想要的操作。经过对 os 的使用,本文把 os 模块的常用的操作进行总结,主要分为以下几个划分:

文件夹操作:即文件夹的创建、修改(改名/移动),查询(查看、遍历)、删除等。

文件操作:即文件的创建、修改、读取、删除等。

(文件夹/文件)路径操作:即文件夹或文件的路径操作,如绝对路径,文件名与路径分割,扩展名分割等

本文涉及常用 的 os 函数的使用展示,主要使用 python 交互模式下进行代码说明。后续操作默认已经引入 os 模块,如下:

import os

复制代码

如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python圈,裙号930900780,可领取python学习资料,会节约很多时间,减少很多遇到的难题。

2 文件夹操作

以本地 E://pythontest 目录作为演示目录,此目录下当前文件如下:

test

│ test.txt

└─test-1

    test-1.txt

复制代码

test 及 test-1 是文件夹,test.txt 及 test-1.txt 是文件。

2.1 查询操作

熟悉 linux 同学应该对 ls / pwd / cd 等操作不陌生,对应的 python 也有对应的方法,主要包括:

listdir : 文件及目录列表

getcwd :获取当前目录

chdir :更换目录

stat :文件及目录基本信息

walk :递归遍历目录

>>> os.chdir("E://pythontest")  # 更改目录

>>> os.getcwd()                # 获取当前目录

'E:\\pythontest'

>>> os.listdir("test")          # 文件及目录列表,相对路径

['test-1', 'test.txt']         

>>> os.listdir("E://pythontest/test")  # 文件及目录列表,绝对路径

['test-1', 'test.txt']

>>> os.stat("test")            # 获取目录信息

os.stat_result(st_mode=16895, st_ino=4503599627377599, st_dev=266147611, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1590833033, st_mtime=1590832647, st_ctime=1590832207)

>>> os.stat("test/test.txt")    # 获取文件信息

os.stat_result(st_mode=33206, st_ino=2251799813692354, st_dev=266147611, st_nlink=1, st_uid=0, st_gid=0, st_size=4, st_atime=1590832653, st_mtime=1590832609, st_ctime=1590832598)

复制代码

其中 stat 函数返回的是文件或者目录的基本信息,具体如下:

st_mode:inode 保护模式

st_ino:inode 节点号。

st_dev:inode 驻留的设备。

st_nlink:inode 的链接数。

st_uid:所有者的用户ID。

st_gid:所有者的组ID。

st_size:普通文件以字节为单位的大小

st_atime:上次访问的时间。

st_mtime:最后一次修改的时间。

st_ctime:创建时间。

日常使用中,我们一般使用 st_size 、st_ctime 及 st_mtime 获取文件大小,创建时间,修改时间。另外,我们看到输出的时间是秒数,在这里提一下,关于日期的转换处理。

(1)秒数转日期时间格式字符串

>>> import time                              # 引入time模块

>>> timestruct = time.localtime(1590803070)  # 转换为时间结构体

>>> print(timestruct)

time.struct_time(tm_year=2020, tm_mon=5, tm_mday=30, tm_hour=9, tm_min=44, tm_sec=30, tm_wday=5, tm_yday=151, tm_isdst=0)

>>> time.strftime("%Y-%m-%d %H:%M:%S",timestruct)  # 格式化时间

'2020-05-30 09:44:30'

复制代码

(2)格式日期时间字符串转秒数

>>> import datetime              # 引入datetime模块

>>> timeobject = datetime.datetime.strptime("2020-05-23 10:00:00","%Y-%m-%d %H:%M:%S") #解析时间字符串为时间对象

>>> timeseconds=time.mktime(timeobject.timetuple())  # 获取时间秒数

>>> print(int(timeseconds))      # 转为int显示

1590199200

复制代码

遍历操作 walk 函数对目录进行递归遍历,返回 root,dirs,files,分别对应当前的遍历的目录,此目录中的子目录及文件。

>>> data = os.walk("test")              # 遍历test目录

>>> for root,dirs,files in data:        # 递归遍历及输出

...    print("root:%s" % root)

...    for dir in dirs:

...      print(os.path.join(root,dir))

...    for file in files:

...      print(os.path.join(root,file))

...

root:test

test\test-1

test\test-2

test\test.txt

root:test\test-1

test\test-1\test-1.txt

root:test\test-2

test\test-2\test-2.txt

复制代码

2.2 创建操作

mkdir :新建单个目录,若目录路径中父目录不存在,则创建失败

makedirs :新建多个目录,若目录路径中父目录不存在,则自动创建

>>> os.mkdir("test")

>>> os.mkdir("test1/test1-1")          # 父目录不存在,报错

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'test1/test1-1'

>>> os.makedirs("test1/test1-1")      # 父目录不存在,自动创建

>>> os.listdir("test1")

['test1-1']

复制代码

2.3 删除操作

rmdir :删除单个空目录,目录不为空则报错

removedirs : 按路径删除递归多级空目录,目录不为空则报错

>>> os.rmdir("test1")                        # 若目录不为空,报错

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

OSError: [WinError 145] 目录不是空的。: 'test1'

>>> os.rmdir("test1/test1-1")

>>> os.removedirs("test1/test1-1")            # 删除多级空目录

>>> os.listdir(".")

['test']

复制代码

由于删除空目录的限制,更多的是使用 shutil 模块中的 rmtree 函数,可以删除不为空的目录及其文件。

2.4 修改操作

rename :重命名目录或文件,可修改文件或目录的路径(即移动操作),若目标文件目录不存在,则报错。

renames :重命名目录或文件,若目标文件目录不存在,则自动创建

>>> os.makedirs("test1/test1-1")

>>> os.rename("test1/test1-1","test1/test1-2")    # test1-1 修改为test1-2

>>> os.listdir("test1")

['test1-2']

>>> os.rename("test1/test1-2","test2/test2-2")    # 由于test2目录不存在,报错

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'test1/test1-2' -> 'test2/test2-2'

>>> os.renames("test1/test1-2","test2/test2-2")    # renames可自动创建不存在的目录

>>> os.listdir("test2")

['test2-2']

复制代码

如果目标路径文件已经存在,那么os.rename()和os.renames()都会报错:FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。

3 文件操作

3.1 查询操作

open/read/close :文件读取

stat :文件信息,详细见前面文件夹中的 stat 说明

>>> f = os.open("test/test.txt", os.O_RDWR|os.O_CREAT)  # 打开文件

>>> str_bytes = os.read(f,100)                          # 读100字节

>>> str = bytes.decode(str_bytes)                      # 字节转字符串

>>> print(str)

test write data

>>> os.close(f)                                        # 关闭文件

复制代码

注意 open/read/close 需要一起操作,其中 open 操作需要指定模式,上述是以读写模式打开文件,若文件不存在则创建文件。各模式具体如下:

flags-- 该参数可以是以下选项,多个使用 "|" 隔开:

os.O_RDONLY:以只读的方式打开

os.O_WRONLY:以只写的方式打开

os.O_RDWR :以读写的方式打开

os.O_NONBLOCK:打开时不阻塞

os.O_APPEND:以追加的方式打开

os.O_CREAT:创建并打开一个新文件

os.O_TRUNC:打开一个文件并截断它的长度为零(必须有写权限)

os.O_EXCL:如果指定的文件存在,返回错误

os.O_SHLOCK:自动获取共享锁

os.O_EXLOCK:自动获取独立锁

os.O_DIRECT:消除或减少缓存效果

os.O_FSYNC :同步写入

os.O_NOFOLLOW:不追踪软链接

3.2 创建操作

前面已提到,使用 open ,指定模式, 若文件不存在,则创建。有点类似 linux 操作中的 touch。

>>> f = os.open("test/test.txt", os.O_RDWR|os.O_CREAT)  # 若文件不存在,则创建

>>> os.close(f)

复制代码

3.3 修改操作

open/write/close :写入文件内容

rename ,renames : 与前面介绍的修改名称、移动操作一致。

>>> f = os.open("test/test.txt", os.O_RDWR|os.O_CREAT)    # 打开文件

>>> os.write(f,b"test write data")                        # 写入内容

15

>>> os.close(f)                                  # 关闭文件

复制代码

3.4 删除

remove :删除文件,注意不能删除目录(使用 rmdir/removedirs)

>>> os.remove("test/test-1")      # 删除目录报错

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'test/test1'

>>> os.remove("test/test.txt")    # 删除文件

>>> os.listdir("test")

['test-1']

复制代码

4 路径操作

在使用文件或目录过程中,经常需要对文件及目录路径进行处理,因此,os 中有一个子模块 path,专门就是处理路径操作的。主要有以下操作:

abspath :返回绝对路径

>>> os.path.abspath("test")

'E:\\pythontest\\test'

复制代码

exists :判断文件或目录是否存在

>>> os.path.exists("test")

True

>>> os.path.exists("test/test.txt")

False

>>> os.path.exists("test/test-1/test-1.txt")

True

复制代码

isfile/isdir :判断是否为文件/目录

>>> os.path.isdir("test")

True

>>> os.path.isfile("test/test-1/test-1.txt")

True

复制代码

basename/dirname:获取路径尾部和路径头部。其实就是以路径中最后一个 / 为分割符,分为头(head) 和尾(tail)两部分,tail 是 basename 返回的内容,head 是 dirname 返回的内容。经常用于获取文件名,目录名等操作

>>> os.path.basename("test/test-1/test-1.txt")  # 文件名

'test-1.txt'

>>> os.path.basename("test/test-1/")    # 空内容

''

>>> os.path.basename("test/test-1")      # 目录名

'test-1'

>>> os.path.dirname("test/test-1/test-1.txt")  # 文件所在目录路径

'test/test-1'

>>> os.path.dirname("test/test-1/")  # 目录路径

'test/test-1'

>>> os.path.dirname("test/test-1")  # 父目录路径

'test'

复制代码

join :合成路径,即把两个参数使用系统路径分割符进行连接,形成完整路径。

>>> os.path.join("test","test-1")  # 连接两个目录

'test\\test-1'

>>> os.path.join("test\\test-1","test-1.txt")  # 连接目录与文件名

'test\\test-1\\test-1.txt'

复制代码

split :分割文件名和文件夹,即把 path 以最后一个斜线"/"为分隔符,切割为 head 和 tail ,以 (head, tail) 元组的形势返回。

>>> os.path.split("test/test-1")    # 分割目录

('test', 'test-1')

>>> os.path.split("test/test-1/")    # 以/结尾的目录分割

('test/test-1', '')

>>> os.path.split("test/test-1/test-1.txt")  # 分割文件

('test/test-1', 'test-1.txt')

复制代码

splitext :分割路径名和文件扩展名,把path 以最后一个扩展名分隔符“.”分割,切割为 head 和 tail ,以 (head, tail) 元组的形势返回。注意与 split 的区别是分隔符的不同。

>>> os.path.splitext("test/test-1") 

('test/test-1', '')

>>> os.path.splitext("test/test-1/")

('test/test-1/', '')

>>> os.path.splitext("test/test-1/test-1.txt")  # 区分文件名及扩展名

('test/test-1/test-1', '.txt')

>>> os.path.splitext("test/test-1/test-1.txt.tmp") # 以最后的"."为分割点

('test/test-1/test-1.txt', '.tmp')

复制代码

5 示例应用

下面以一些平时使用到的场景,对前面的操作函数进行综合使用。

5.1 批量修改文件名

def batch_rename(dir_path):

    itemlist = os.listdir(dir_path)

    # 获取目录文件列表

    for item in itemlist:

        # 连接成完整路径

        item_path = os.path.join(dir_path, item)

        print(item_path)

        # 修改文件名

        if os.path.isfile(item_path):

            splitext = os.path.splitext(item_path)

            os.rename(item_path, splitext[0] + "-副本" + splitext[1])

复制代码

5.2 遍历目录及子目录下所有指定扩展名的文件

def walk_ext_file(dir_path,ext):

    # 遍历

    for root, dirs, files in os.walk(dir_path):

        # 获取文件名称及路径

        for file in files:

            file_path = os.path.join(root, file)

            file_item = os.path.splitext(file_path)

            # 输出指定扩展名的文件路径

            if ext == file_item[1]:

                print(file_path)

复制代码

5.3 按修改时间排序指定目录下的文件

def sort_file(dir_path):

    # 排序前

    itemlist = os.listdir(dir_path)

    print(itemlist)

    # 正向排序

    itemlist.sort(key=lambda filename: os.path.getmtime(os.path.join(dir_path, filename)))

    print(itemlist)

    # 反向排序

    itemlist.sort(key=lambda filename: os.path.getmtime(os.path.join(dir_path, filename)), reverse=True)

    print(itemlist)

    # 获取最新修改的文件

    print(itemlist[0])

复制代码

6 总结

在需要对文件或者目录进行操作时,python 是一个简单快速选择。本文通过 python 的标准内置 os 模块及子模块 os.path 的常用方法进行介绍,最后结合使用场景进行综合使用。相信已经满足大家对文件及目录操作的大部分需求。

最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以进裙930900780领取。

本文章素材来源于网络,如有侵权请联系删除。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341