13

【python测试开发栈】—帮你总结Python os模块高频使用的方法

 4 years ago
source link: https://segmentfault.com/a/1190000021434900
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python中的os模块是主要和系统操作相关的模块,在平时的工作中会经常用到,花时间整理了os模块的高频使用方法,同时整理出使用时需要注意的点。归纳来讲,os模块的方法可以分为:目录操作、文件操作、路径操作、系统操作等四大类,我们接下来依次进行介绍。

目录操作相关

创建、删除、重命名目录

# 当前目录下创建目录,注意第二个参数mode,在Windows被忽略
    os.mkdir("test_folder")
    # 删除目录,如果目录不为空,则抛出OSError:[Errno 66] Directory not empty
    os.rmdir("test_folder")
    # 遍历创建目录,可以创建多个目录,其中exist_ok为False,表示目录存在抛出异常。
    os.makedirs("a/b/c", exist_ok=False)
    # 遍历删除目录,可以直接,注意如果目录不为空,会抛出OSError:[Errno 66] Directory not empty
    os.removedirs("a/b/c")
    # 对文件或者目录进行重命名,不能对路径做变更
    os.rename("a", "b")
    # os.rename的升级版本,可以重命名文件,也可以重命名文件的上级目录。
    os.renames("b", "a/b")

遍历目录

# 对目录a下的文件进行遍历,返回目录下的名字列表,注意不会遍历子目录
    file_name_list = os.listdir("a")
    print(file_name_list)

    '''
        功能:会递归遍历对目录a下的文件和目录
        参数:topdown表示遍历目录的优先级(True先遍历根目录,False先遍历子目录)
             onerror 当walk遇到错误时会调用
        返回值:
            parent 指的是父目录,
            dir_name返回parent目录下所有的目录
            file_name返回parent目录下所有的文件
    '''
    list_result = os.walk("a", topdown=True, onerror=None, followlinks=False)
    for parent, dir_name, file_name in list_result:
        print(parent)
        print(dir_name)
        print(file_name)
        print("============")

    # 和listdir类似,都是对第一层目录遍历,区别在于scandir返回的是迭代器
    with os.scandir("a") as it:
        print("*"*12)
        for entry in it:
            print(entry.name)

需要注意的是,如果要遍历的目录下文件数量比较多,比如数百万个文件,那么就可以使用os.scandir(),因为如果这时使用listdir()会造成内存紧张。

获取目录

# 获取当前工作目录所在的绝对路径
    print(os.getcwd())

    # 返回.. 表示当前目录的上级目录
    print(os.pardir)

    # 返回上级目录,这里用到了os.path.abspath,获取绝对路径
    print(os.path.abspath(os.path.dirname(os.getcwd())))

    # 用于改变当前工作目录
    os.chdir("a")
    print(os.getcwd())

判断目录

# 判断路径a是否存在
    print(os.path.exists("a"))

    # 判断路径a是否是目录
    print(os.path.isdir("a"))

    # 判断路径a是否是文件
    print(os.path.isfile("a"))

文件属性

'''
    功能:返回文件/目录对应的属性
    返回值:st_mode(权限模式)=16877, st_ino(inode节点号)=12897368202, 
    st_dev(inode所在设备号)=16777220, st_nlink(inode链接数)=5, st_uid(文件所有者id)=501, 
    st_gid(文件所有者的组id)=20, st_size(文件大小)=160, st_atime(上次访问的时间)=1577449111, 
    st_mtime(最后一次修改的事件)=1577449111, st_ctime(创建时间)=1577449111)
    '''
    print(os.stat("."))

    # 同样,os也提供了单独获取某个属性的方法
    print(os.path.getatime("."))
    print(os.path.getctime("."))
    print(os.path.getmtime("."))
    print(os.path.getsize("."))

    # 修改文件的访问时间和修改时间
    os.utime(".", (1577449111, 1577449111))

在上面注释中提到的inode,主要用来存储文件的"元信息",比如文件的创建时间、文件的大小等,中文名叫作"索引节点"。

读写文件

# Python的os提供了open和write方法来读写文件
  # 打开文件
  fd = os.open("test3.txt", os.O_RDWR | os.O_CREAT)
  # 这里返回的是一个文件描述符
  print(fd)
  # 写入字符串
  os.write(fd, b"This is test")
  # 将字符串刷新到硬盘上
  os.sync()
  # 关闭文件
  os.close(fd)

  # 作为对比,Python提供了open方法可以更方便的操作文件,所以我们一般直接使用open方法。
  with open("a/test3.txt", "wb") as f:
    # 这里返回的是一个操作文件的BufferedWriter对象
    print(f)
    f.write(b"aaaaaaaaa")

路径操作

# 获取路径的相对路径
    print(os.path.abspath("."))
    # 判断路径是否是相对路径
    print(os.path.isabs("."))
    # 将路径拼接在一起
    print(os.path.join(os.getcwd(), "a","b"))
    # 将传入的路径的最后一级目录/文件拆分开,比如:传入a/b/c/d  返回: a/b/c , d
    print(os.path.split(os.getcwd()))
    # 返回传入路径所在的目录,比如:传入a/b/c/d  返回:/a/b/c
    print(os.path.dirname(os.getcwd()))
    # 将传入path分割为路径和扩展,比如:传入a/b/c/d.txt  返回('a.b/c/d', '.text')
    print(os.path.splitext(os.path.abspath("./a/test3.txt")))

执行系统命令

# 注意这里执行的命令一定是在执行的操作系统存在的命令,比如在linux系统用ls,在windows系统用dir
    # 在当前进程中打开一个子shell(子进程)来执行命令
    # 返回值:命令的执行状态 0 执行成功、非0,表示执行不成功。 会将命令的执行结果写入到stdout中,也就是控制台。
    print(os.system("la"))

    print("================")
    '''
        参数:cmd:要执行的命令。
             mode:打开文件的模式,默认为'r',用法与open()相同。
             buffering:0意味着无缓冲;1意味着行缓冲;其它正值表示使用参数大小的缓冲。
             负的bufsize意味着使用系统的默认值,一般来说,对于tty设备,它是行缓冲;对于其它文件,它是全缓冲。
        返回:这个方法会返回一个管道,返回一个连接管道的文件对象,比如为f,可以通过f.readlines()和f.read()来读取返回值。
    '''
    with os.popen("ls", "r", 1) as p:
        print(type(p))
        r = p.read()
        print(r)
    print("end")

不过Python提供了更强大的subprocess模块,使用subprocess.popen()方法会更加灵活。我们后面会专门写文章来介绍subprocess这个模块的各种方法的使用。

系统操作

# 返回当前进程的id
    print(os.getpid())
    # 返回操作系统的信息
    print(os.uname())
    # 返回系统的环境变量
    print(os.environ)
    # 返回系统的环境变量,PATH对应的值
    print(os.environ.get('PATH'))

总结

上面总结了python3中os模块常用的方法,主要围绕对路径、目录及系统命令的操作,大家在平时使用过程中可以灵活使用上面的各种方法,有时候需要多个方法搭配使用。我给大家留两个练习题,这是我之前写python脚本碰到的问题:

  • 获取某个目录下面最新的文件
  • 将所有以error.log结尾的文件,全部放到某个对应目录下。

大家可以思考下,然后在评论区写下你的答案。

关注【公众号:软件测试布道师】,回复【python】,即可获取【python自动化及编程实践资料】

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK