os模块常用方法整理

python标准库中的模块比较多,对一个python程序员来说,标准库是不得不经常检阅的资料,python语言因有了如此丰富的标准库所以才显得那么耀眼,对我这个python菜鸟而言,python之路还很长,坚持吧,坚持每天都去标准库翻阅一个模块来看看。本文记录os这个模块的常用方法。

os模块为用户提供一个各种各样的操作系统的一个接口抽象,这里把常用的功能整理如下。

name属性

在python语言中要使用一个模块需要使用import语句把此模块导进到当前的命名空间里。os模块中的name属性打印出当前操作系统所属的平台,类linux系统输出posix,window用户输出nt

1
2
3
4
In [1]: import os

In [2]: os.name
Out[2]: 'posix'

uname()

返回当前操作系统的信息,如下:

1
2
In [30]: os.uname()
Out[30]: posix.uname_result(sysname='Linux', nodename='neal-System-Product-Name', release='4.4.0-36-generic', version='#55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016', machine='x86_64')

getcwd()和chdir(path)

getcwd方法是获取当前的工作路径,而chdir方法是切换工作路径,如下:

1
2
3
4
5
6
7
In [3]: os.getcwd()
Out[3]: '/home/neal/private/sync/temp/logscan-api'

In [4]: os.chdir('/tmp')

In [5]: os.getcwd()
Out[5]: '/tmp'

fsencode(filename)和fsdecode(filename)

表示使用文件系统来编码或解码文件名,fsencode方法接收str,返回bytes,fsdecode方法接收bytes,返回str,如下:

1
2
3
4
5
6
7
In [7]: encode = os.fsencode('/tmp/jdk.sh')

In [8]: encode
Out[8]: b'/tmp/jdk.sh'

In [9]: os.fsdecode(encode)
Out[9]: '/tmp/jdk.sh'

getenv(key, default=None)和getenvb(key, default=None)方法

表示获取指定环境变量的值,getenv方法接收str,返回str,getenvb方法接收bytes,返回bytes,如下:

1
2
3
4
5
6
7
8
In [27]: os.getenv('PATH')
Out[27]: '/home/neal/.pyenv/versions/logscan-api/bin:/home/neal/.pyenv/libexec:/home/neal/.pyenv/plugins/python-build/bin:/home/neal/.pyenv/plugins/pyenv-virtualenv/bin:/home/neal/opt/jdk1.8.0_65/bin:/home/neal/.pyenv/plugins/pyenv-virtualenv/shims:/home/neal/.pyenv/shims:/home/neal/.pyenv/bin:/home/neal/bin:/usr/local/jdk1.8.0_65/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/neal/opt/node-v6.4.0-linux-x64/bin:/home/neal/opt/pycharm/bin'

In [28]: os.getenvb(b'PATH')
Out[28]: b'/home/neal/.pyenv/versions/logscan-api/bin:/home/neal/.pyenv/libexec:/home/neal/.pyenv/plugins/python-build/bin:/home/neal/.pyenv/plugins/pyenv-virtualenv/bin:/home/neal/opt/jdk1.8.0_65/bin:/home/neal/.pyenv/plugins/pyenv-virtualenv/shims:/home/neal/.pyenv/shims:/home/neal/.pyenv/bin:/home/neal/bin:/usr/local/jdk1.8.0_65/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/neal/opt/node-v6.4.0-linux-x64/bin:/home/neal/opt/pycharm/bin'

In [29]: print(os.getenv('PAT'))
None

listdir(path=’.’)

返回指定路径下的文件,默认是当前目录,返回的是一个list,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
In [5]: os.getcwd()
Out[5]: '/home/neal/private/sync/temp/logscan-api'

In [6]: os.listdir()
Out[6]:
['app.py',
'application.conf',
'.git',
'test_scripts',
'.gitignore',
'.python-version',
'tornado-4.4.1.tar.gz',
'logscan',
'.idea',
'logscan-api.xmind']

In [7]: os.listdir(path='/tmp')
Out[7]:
['+~JF3877189641662443938.tmp',
'fcitx-qimpanel:0.pid',
'.ICE-unix',
'.com.google.Chrome.fVrOnx',
'.font-unix',
'systemd-private-c3a4fbe0a0c643faa8d68d5d7fd1599d-rtkit-daemon.service-gcBEfw',
'+~JF8633920933949119482.tmp',
'.X0-lock',
'fcitx-socket-:0',
'.X11-unix',
'config-err-s5rtZ6',
'hsperfdata_neal',
'systemd-private-c3a4fbe0a0c643faa8d68d5d7fd1599d-colord.service-GLdwh0',
'unity_support_test.0',
'orbit-neal',
'+~JF1201684757014287454.tmp',
'.xrdp',
'test',
'jdk.sh',
'+~JF7598506182566291945.tmp',
'.wine-1000',
'.Test-unix',
'iconcache-6NAcAO',
'+~JF1811871931355839416.tmp',
'.XIM-unix',
'systemd-private-c3a4fbe0a0c643faa8d68d5d7fd1599d-systemd-timesyncd.service-ERVXh5']

mkdir(path, mode=0o777, *, dir_fd=None)和makedirs(name, mode=0o777, exist_ok=False)

mkdir不能递归的创建目录,而makedirs可以递归创建,mode=0o777mode=0o775的效果是一样的,目录的权限都是drwxrwxr-x,不知道为何?测试如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
In [24]: os.listdir('/tmp/test')
Out[24]: []

In [25]: os.mkdir('/tmp/test/a')

In [26]: os.listdir('/tmp/test')
Out[26]: ['a']

In [27]: os.mkdir('/tmp/test/b/bb')
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-27-0ce8d4717d44> in <module>()
----> 1 os.mkdir('/tmp/test/b/bb')

FileNotFoundError: [Errno 2] No such file or directory: '/tmp/test/b/bb'

In [28]: os.makedirs('/tmp/test/b/bb')

In [29]: os.listdir('/tmp/test')
Out[29]: ['b', 'a']

再来看看创建目录的权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
neal@neal-System-Product-Name:test$ pwd
/tmp/test
neal@neal-System-Product-Name:test$ ll
总用量 16
drwxrwxr-x 4 neal neal 4096 9月 15 15:32 ./
drwxrwxrwt 17 root root 4096 9月 15 15:33 ../
drwxrwxr-x 2 neal neal 4096 9月 15 15:31 a/
drwxrwxr-x 3 neal neal 4096 9月 15 15:32 b/
neal@neal-System-Product-Name:test$ ll b
总用量 12
drwxrwxr-x 3 neal neal 4096 9月 15 15:32 ./
drwxrwxr-x 4 neal neal 4096 9月 15 15:32 ../
drwxrwxr-x 2 neal neal 4096 9月 15 15:32 bb/

remove(path, *, dir_fd=None)与removedirs(name)

remove只能删除文件,如果删除的是一个目录会报错,removedirs递归的删除空目录,如果是非空目录,依然会报错,测试如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [35]: os.listdir('/tmp/test/a')
Out[35]: ['1.txt', 'aa']

In [36]: os.remove('/tmp/test/a/1.txt')

In [37]: os.listdir('/tmp/test/a')
Out[37]: ['aa']

In [38]: os.remove('/tmp/test/a')
---------------------------------------------------------------------------
IsADirectoryError Traceback (most recent call last)
<ipython-input-38-fdb1cdf283f6> in <module>()
----> 1 os.remove('/tmp/test/a')

IsADirectoryError: [Errno 21] Is a directory: '/tmp/test/a'
1
2
3
4
5
6
7
8
9
10
11
neal@neal-System-Product-Name:tmp$ pwd
/tmp
neal@neal-System-Product-Name:tmp$ tree test/
test/
├── a
│   └── aa
└── b
├── 2.txt
└── bb

4 directories, 1 file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
In [46]: os.removedirs('/tmp/test/a/aa')

In [47]: os.listdir('/tmp/test')
Out[47]: ['b']

In [48]: os.removedirs('/tmp/test/b/bb')

In [49]: os.listdir('/tmp/test/b')
Out[49]: ['2.txt']

In [50]: os.removedirs('/tmp/test/b')
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-50-03112f9e37d0> in <module>()
----> 1 os.removedirs('/tmp/test/b')

/home/neal/.pyenv/versions/3.5.2/lib/python3.5/os.py in removedirs(name)
257
258 """
--> 259 rmdir(name)
260 head, tail = path.split(name)
261 if not tail:

OSError: [Errno 39] Directory not empty: '/tmp/test/b'

rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)与renames(old, new)

两个方法都表示重命名文件或目录,如果dst的名称已存在,那将会被替换,测试如下:

1
2
3
4
5
6
7
8
9
10
neal@neal-System-Product-Name:test$ pwd
/tmp/test
neal@neal-System-Product-Name:test$ tree .
.
├── test1
│   └── 1.txt
└── test2
└── 2.txt

2 directories, 2 files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
In [4]: os.rename('/tmp/test/test1', '/tmp/test/test2')
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-4-0d34cb8a001e> in <module>()
----> 1 os.rename('/tmp/test/test1', '/tmp/test/test2')

OSError: [Errno 39] Directory not empty: '/tmp/test/test1' -> '/tmp/test/test2'

In [5]: os.rename('/tmp/test/test1', '/tmp/test/test3')

neal@neal-System-Product-Name:test$ tree .
.
├── test2
│   └── 2.txt
└── test3
└── 1.txt

2 directories, 2 files

In [8]: os.renames('/tmp/test/test3', '/tmp/test/test1')

neal@neal-System-Product-Name:test$ tree .
.
├── test1
│   └── 1.txt
└── test2
└── 2.txt

2 directories, 2 files

两个方法使用方法相似。

更多os模块的方法请看官方文档。

文章目录
  1. 1. name属性
  2. 2. uname()
  3. 3. getcwd()和chdir(path)
  4. 4. fsencode(filename)和fsdecode(filename)
  5. 5. getenv(key, default=None)和getenvb(key, default=None)方法
  6. 6. listdir(path=’.’)
  7. 7. mkdir(path, mode=0o777, *, dir_fd=None)和makedirs(name, mode=0o777, exist_ok=False)
  8. 8. remove(path, *, dir_fd=None)与removedirs(name)
  9. 9. rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)与renames(old, new)
|