Python3的os模块

版权声明:版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/swinfans/article/details/85548961

os 模块提供了丰富的方法用来处理文件和目录,下面列举一些我认为常用的一些方法。

  • os.getcwd()

    获取当前路径。

    >>> os.getcwd()
    '/User/tester
    
  • os.listdir(path=None)

    返回一个包含指定目录下文件和目录的名称的列表,并且不包括 ... 。若不指定目录,则默认为当前目录。若传入的参数是 bytes 类型,则返回的列表元素的类型也是 bytes 类型, 否则则为str类型。

    >>> os.listdir()
    ['hello_world.py', '1.txt', '.ssh']
    >>> os.listdir('./.ssh')
    ['config', 'id_rsa', 'id_rsa.pub']
    
  • os.chdir()

    切换工作目录到指定的路径下,如果操作成功,则返回True,如果操作失败,则返回False。如果指定的路径不存在或者无访问权限,则抛出异常。

    >>> os.chdir('../')
    >>> os.chdir('./project')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    PermissionError: [Errno 13] Permission denied: './project'
    
  • os.mkdir(path, mode=511)

    创建一个目录,并指定访问权限(在windows平台下, mode参数将会被忽略)。默认的访问权限为 511,表示8进制的 0o777,即拥有者,用户组和其他用户均具有读、写和执行的权限。

    >>> os.mkdir('p1') # 创建一个名称为‘p1’ 的目录,并且权限被默认被设定为‘rwxrwxrwx’
    >>> os.mkdir('p2', 0o755) # 创建一个名称为‘p2’的目录,并且设定权限为‘rwxr-xr-x’
    
    
  • os.makedirs(name, mode=511, exist_ok=False)

    递归地创建目录并设置访问权限,类似于linux中的 mkdir -p。默认的访问权限为 511,表示8进制的 0o777,即拥有者,用户组和其他用户均具有读、写和执行的权限。如果 exist_ok 参数值为 False,则当指定的目录已存在时,抛出FileExistsError 异常,若 exist_ok 参数值为 True,则可以成功执行。

    >>> os.makedirs('p1/c1') # 在当前目录下创建文件夹‘p1’, 然后在‘p1’下再创建文件夹’c1‘
    >>> os.makedirs('p1/c1')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python.7/os.py", line 221, in makedirs
      mkdir(name, mode)
    FileExistsError: [Errno 17] File exists: 'p1/c1'
    >>> os.makedirs('p1/c1/c2', 0o755, True) # 重新创建目录并将访问权限设置为‘rwxr-xr-x’
    
  • os.rmdir(path)

    删除指定的目录,若目录非空,则抛出OSError异常。

    >>> os.listdir('projects')
    ['p1', 'p3']
    >>> os.listdir('projects/p1')
    []
    >>> os.rmdir('projects') # 删除非空文件夹‘projects’
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    OSError: [Errno 66] Directory not empty: 'projects'
    >>> os.rmdir('projects/p1') # 删除空目录‘p1’
    >>> os.listdir('projects')
    ['p3']
    
  • os.removedirs(path)

    递归删除指定的目录。

    若指定的是一个文件,则引发 NotADirectoryError 异常

    若指定的目录不为空,则引发OSError异常。

    # 当前目录下存在文件夹‘p1’,‘p1’中存在目录‘c1’和文件‘test1’
    ... os.removedirs('p1/c1/test1')  # 指定的路径为一个文件
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/Users/neochen/.virtualenvs/Test/bin/../lib/python.7/os.py", line 239, in removedirs
      rmdir(name)
    NotADirectoryError: [Errno 20] Not a directory: 'p1/c1/test1'
    >>> os.removedirs('p1/c1')  # 指定的目录非空
    Traceback (most recent call last):
    File "<stdin>", line 2, in <module>
    File "/Users/neochen/.virtualenvs/Test/bin/../lib/python.7/os.py", line 239, in removedirs
      rmdir(name)
    OSError: [Errno 66] Directory not empty: 'p1/c1'
    >>> os.remove('p1/c1/test1')
    >>> os.removedirs('p1/c1')
    
  • os.remove(path)

    删除指定的文件。若‘path’为一个目录,则引发PermissionError 异常

    >>> os.listdir()
    ['p3', 'test.sh']
    >>> os.remove('test.sh')
    >>> os.listdir()
    ['p3']
    >>> os.remove('p3')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    PermissionError: [Errno 1] Operation not permitted: 'p3'
    
  • os.rename(src, dst)

    移动并重命名文件或目录

    srcdst指向的均为目录,当dst指向的目录非空时,将抛出OSError异常。

    src指向的是目录,而dst指向的不是目录时,将抛出NotADirectoryError异常。

    src指向的不是目录,而dst指向的是目录时,将抛出IsADirectoryError异常。

    >>> # 当前目录下存在文件夹‘p1’和‘p2’,并且p2非空
    >>> os.listdir()
    ['p1', 'p2']
    >>> os.rename('p1', 'p2')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    OSError: [Errno 66] Directory not empty: 'p1' -> 'p2'
    >>> os.remove('p2/file1')
    >>> os.rename('p1', p2)
    >>> os.listdir()
    ['p2']
    
  • os.renames(src, dst)

    递归的移动并重命名目录或文件。

    os.rename 类似,但会自动创建 dst 指定的路径中不存在的中间目录;在重命名后,若src指向的路径中最右端的目录为空,则该目录将被删除,这个删除操作将会递归地进行,直到指向的目录非空为止。

    >>> os.listdir()
    ['p1']
    >>> os.renames('p1/c1/c2/test.txt', 'p2/test1.txt')
    >>> os.listdir()
    ['p2']
    
  • access(path, mode)

    使用当前的uid/gid 测试指定的目录是否存在,以及是否有相应的读、写、执行权限。

    • os.F_OK 测试文件或目录是否存在

    • os.R_OK 测试当前uid/gid对指定的目录或文件是否有读权限

    • os.W_OK 测试当前uid/gid对指定的目录或文件是否有写权限

    • os.X_OK 测试当前uid/gid对指定的目录或文件是否有执行权限

    >>> os.listdir() # 当前目录下只存在文件夹‘p1’
    ['p1']
    >>> os.access('p1', os.F_OK) # 测试当前目录下是否存在文件或目录‘p1’
    True
    >>> os.access('p2', os.F_OK) # 测试当前目录下是否存在文件或目录‘p2’
    False
    >>> os.mkdir('p2', 0o555) # 在当前目录下创建一个目录‘p2’,并且指定所有用户对该目录只有读和执行的权限
    >>> os.access('p2', os.F_OK) 测试当前目录下是否存在文件或目录‘p2’
    True
    >>> os.access('p2', os.R_OK) # 测试当前gid/uid对目录‘p2’ 是否有读权限
    True
    >>> os.access('p2', os.W_OK) # 测试当前gid/uid对目录‘p2’ 是否有写权限
    False
    >>> os.access('p2', os.X_OK) # 测试当前gid/uid对目录‘p2’ 是否有执行权限
    True  
    
  • os.chmod(path, mode)

    更改目录或文件的访问权限。

    若当前用户不是该文件或者目录的所有者,那么将需要超级用户权限来进行此操作。

    >>> os.chmod('p2', 0o777) # 将目录‘p2’的访问权限设置为‘rwxrwxrwx’
    
  • os.chown(path, uid, gid)

    更改文件或目录的所有者,若不修改uid或者gid,可将其值设置为 -1

    执行该操作需要超级用户权限,否则会引发PermissionError异常

    >>> os.stat('p3').st_uid, os.stat('p4').st_gid  # 查看文件‘p3’拥有者的用户id和组id
    (501, 20)
    >>> os.chown('p3', 0, 0) # 将目录p3的uid设置为501,将gid设置为20。
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    PermissionError: [Errno 1] Operation not permitted: 'p3'
    

    以root用户角色进入python的交互模式下,再次执行

    >>> os.chown('p3', 0, 0) # 将目录p4的uid设置为0,将gid设置为0。
    >>> os.stat('p3').st_uid, os.stat('p3').st_gid
    (0, 0)
    
  • os.open(file, flags, mode=0o777)

    打开一个文件,并设置打开选项与访问权限,返回文件对应的描述符。默认的访问权限为777

    要设置多个打开选项,可以使用|进行连接

    其中,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_CREAT一起使用时,如果指定的文件存在,则返回错误

    • os.O_SHLOCK: 自动获取共享锁

    • os.O_EXLOCK: 自动获取独立锁

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

    • os.O_FSYNC : 同步写入

    • os.O_NOFOLLOW: 不追踪软链接

    >>> os.listdir()
    []
    >>> # 创建一个文件,并以读写的方式打开
    ... fd = os.open('1.txt', os.O_CREAT|os.O_RDWR)
    >>> # 向打开的文件描述符中写入数据
    ... os.write(fd, b'this is a test file\n')
    20
    >>> # 关闭文件描述符
    ... os.close(fd)
    >>> os.listdir()
    ['1.txt']
    >>> f = open('1.txt')
    >>> f.readline()
    'this is a test file\n'
    
  • os.write(fd, data)

    bytes类型的对象data写入指定的文件描述符fd中,并返回写入的字节数。若data参数指定的不是bytes类型的对象,则引发TypeError异常。

    >>> fd = os.open('1.txt', os.O_APPEND|os.O_WRONLY)
    >>> os.write(fd, 'not bytes object')
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: a bytes-like object is required, not 'str'
    >>> os.write(fd, b'bytes object\n')
    13
    >>> os.close(fd)
    >>> f = open('1.txt')
    >>> next(f)
    'this is a test file\n'
    >>> next(f)
    'bytes object\n'
    
  • os.close(fd)

    关闭指定的文件描述符

    上文的os.writeos.open方法中已经演示了这个方法的使用,不再赘述。

  • os.read(fd, n)

    从指定的文件描述符fd中读取最多n个字节,返回包含读取字节的字节字符串。

    若已经读取到文件末尾,继续读取将会返回空的字节字符串。

    >>> os.system(cat 3.txt)
    >>> os.system('cat 3.txt && wc -c 3.txt')
    1
    hello world
    i love python
          28 3.txt
    0      
    >>> fd = os.open('3.txt', os.O_RDONLY)
    >>> os.read(fd, 28)
    b'1\nhello world\ni love python\n'
    >>> os.read(fd, 5)
    b''
    
  • os.system(command)

    在子shell中执行命令,并返回命令执行的退出状态码。

    >>> result = os.system('wc 3.txt')
    >>> result = os.system('wc 3.txt')
         3       6      28 3.txt
    >>> result
    0
    
  • os.dup(fd)

    复制文件描述符,并返回新的文件描述符。

    >>> fd = os.open('3.txt', os.O_RDWR|os.O_APPEND)
    >>> fd1 = os.dup(fd)
    >>> fd
    13
    >>> fd1
    14
    >>> os.write(fd1, b'a new line\n')
    11
    >>> os.close(fd)
    >>> os.close(fd1)
    
  • os.dup2(fd, fd2)

    将一个文件描述符fd复制到另一个文件描述符fd2

    >>> f = open('stdout.txt', 'a')
    # 将这个文件描述符代表的文件,传递给 1 描述符指向的文件(也就是 stdout),即将输出重定向到文件stdout.txt
    ... os.dup2(f.fileno(), 1)
    >>> f.close()
    # print 输出到标准输出流,就是文件描述符1,对应的内容将被写入文件 stdout.txt
    ... print('the first line')
    >>> print('the second line')
    

    打开一个shell,查看文件stdout.txt的内容

    $ cat stdout.txt
    the first line
    the second line
    
  • os.closerange(fd_low, fd_high)

    关闭从fd_lowfd_hight的文件描述符,其中包括fd_low而不包括fd_hight

    >>> fd1 = os.open('1.txt', os.O_RDONLY)
    >>> fd2 = os.open('2.txt', os.O_RDONLY)
    >>> fd1
    3
    >>> fd2
    4
    >>> os.read(fd1, 4)
    b'this'
    >>> os.read(fd2, 4)
    b'this'
    >>> os.closerange(fd1, fd2 + 1)  # 关闭从3到5的文件描述符
    >>> os.read(fd1, 3)  # 关闭后将无法读取文件描述符对应的文件的内容
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 9] Bad file descriptor
    >>> os.read(fd2, 3)  # 关闭后将无法读取文件描述符对应的文件的内容
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 9] Bad file descriptor
    
  • os.link(src, dst)

    为文件 src 创建硬链接 dst

    >>> os.listdir()
    ['hello_world.py', 'test']
    >>> os.listdir('./test')
    []
    >>> os.link('hello_world.py', './test/hw.py')
    >>> os.listdir('./test')
    ['hw.py']
    
  • os.symlink(src, dst)

    为文件 src 创建软链接 dst

    注意:src需要使用绝对路径,否则创建的软链接将不可用。

    >>> os.listdir()
    ['hello_world.py', 'test']
    >>> os.listdir('./test')
    ['hw.py']
    >>> os.symlink('/Users/neochen/StudyWP/hello_world.py', 'test/shw.py')
    >>> os.listdir('./test')
    ['hw.py', 'shw.py']
    
  • os.unlink(path)

    os.remove(path) 作用相同。

  • os.scandir(path)

    返回给定路径的DirEntry对象的迭代器。若不指定path的值,默认当前路径。

    DirEntry类型的对象有如下方法和属性:

    • is_dir() 判断是否是目录

    • is_file() 判断是否是常规文件

    • is_symlink() 判断是否是软链接

    • inode() 返回文件的inode

    • stat() 返回文件的stat信息

    • name 返回文件的basename

    • path 返回文件的路径

    >>> fi = os.scandir()
    >>> type(fi)
    <class 'posix.ScandirIterator'>
    >>> next(fi)
    <DirEntry '.DS_Store'>
    >>> f = next(fi)
    >>> f
    <DirEntry 'hello_world.py'>
    >>> f.is_file()
    True
    >>> f.is_dir()
    False
    >>> f.is_symlink()
    False
    >>> f.stat()
    os.stat_result(st_mode=33188, st_ino=7703131, st_dev=16777224, st_nlink=1, st_uid=501, st_gid=20, st_size=21, st_atime=1546350121, st_mtime=1546309241, st_ctime=1546326665)
    >>> f.name
    'hello_world.py'
    >>> f.path
    './hello_world.py'
    
  • os.environ

    返回包含当前系统所有环境变量的一个mapping对象。其中的每个键值对表示一个环境变量名和其对应的值,可以进行类似于字典的大部分操作。这个mapping对象是在第一次导入os模块时生成的,除非直接修改这个mapping对象,否则其他对环境变量做的更改不会影响到这个mapping对象。修改这个mapping对象也只对当前进程及其子进程有效,不会影响到其他进程。

    >>> os.environ['SHELL']
    '/bin/bash'
    >>> os.environ['JAVA_HOME']
    '/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home'
    >>> os.environ['SHELL'] = '/bin/sh'
    >>> os.environ['SHELL'] 
    '/bin/sh'
    >>> os.system('echo $SHELL')
    /bin/sh
    0
    >>> exit()
    $ echo $SHELL
    /bin/bash
    
  • os.getenv(key, default=None)

  • os.getenvb(key, default=None)

    返回名称为key的环境变量的值,若该环境变量不存在,则默认返回None。可以通过default参数设置指定的环境变量不存在时的返回值。在Unix操作系统下,返回由sys.getfilesystemencoding()方法返回的编码格式和错误处理方式为surrogateescape进行编码后的值。如果想要返回不同编码的环境变量的值,可以使用os.getenvb(key, value=None)方法得到包含环境变量值的字节字符串,然后指定解码方式进行解码。

    >>> os.getenv('SHELL')
    '/bin/bash'
    >>> os.getenv('JAVA_HOME')
    '/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home'
    >>> os.getenvb(b'JAVA_HOME')
    b'/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home'
    >>> os.getenvb(b'JAVA_HOME').decode('utf-8')
    '/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home'
    

猜你喜欢

转载自blog.csdn.net/swinfans/article/details/85548961