python标准库中的模块比较多,对一个python程序员来说,标准库是不得不经常检阅的资料,python语言因有了如此丰富的标准库所以才显得那么耀眼,对我这个python菜鸟而言,python之路还很长,坚持吧,坚持每天都去标准库翻阅一个模块来看看。本文记录os这个模块的常用方法。
os模块为用户提供一个各种各样的操作系统的一个接口抽象,这里把常用的功能整理如下。
name属性
在python语言中要使用一个模块需要使用import语句把此模块导进到当前的命名空间里。os模块中的name属性打印出当前操作系统所属的平台,类linux系统输出posix,window用户输出nt。
1
2
3
4In [1]: import os
In [2]: os.name
Out[2]: 'posix'
uname()
返回当前操作系统的信息,如下:
1
2In [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
7In [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
7In [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
8In [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
44In [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=0o777与mode=0o775的效果是一样的,目录的权限都是drwxrwxr-x,不知道为何?测试如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21In [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)
in ()
----> 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
13neal@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
15In [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)
in ()
----> 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
11neal@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
24In [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)
in ()
----> 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
10neal@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
29In [4]: os.rename('/tmp/test/test1', '/tmp/test/test2')
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
in ()
----> 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模块的方法请看官方文档。