标准库(3)
你们要谨慎行事,不要像愚昧人,当像智慧人。要爱惜光阴,因为现今的世代邪恶。不要作糊涂人,要明白主的旨意如何。不要醉酒,酒能使人放荡,乃要被圣灵充满。(EPHESIANS 5:15-18)
标准库(3)
OS
os模块提供了访问操作系统服务的功能,它所包含的内容比较多,有时候感觉很神秘。
>>> import os>>> dir(os)['EX_CANTCREAT', 'EX_CONFIG', 'EX_DATAERR', 'EX_IOERR', 'EX_NOHOST', 'EX_NOINPUT', 'EX_NOPERM', 'EX_NOUSER','EX_OK', 'EX_OSERR', 'EX_OSFILE', 'EX_PROTOCOL', 'EX_SOFTWARE', 'EX_TEMPFAIL', 'EX_UNAVAILABLE', 'EX_USAGE', 'F_OK', 'NGROUPS_MAX', 'O_APPEND', 'O_ASYNC', 'O_CREAT', 'O_DIRECT', 'O_DIRECTORY', 'O_DSYNC', 'O_EXCL', 'O_LARGEFILE', 'O_NDELAY', 'O_NOATIME', 'O_NOCTTY', 'O_NOFOLLOW', 'O_NONBLOCK', 'O_RDONLY', 'O_RDWR', 'O_RSYNC', 'O_SYNC', 'O_TRUNC', 'O_WRONLY', 'P_NOWAIT', 'P_NOWAITO', 'P_WAIT', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'ST_APPEND', 'ST_MANDLOCK', 'ST_NOATIME', 'ST_NODEV', 'ST_NODIRATIME', 'ST_NOEXEC', 'ST_NOSUID', 'ST_RDONLY', 'ST_RELATIME', 'ST_SYNCHRONOUS', 'ST_WRITE', 'TMP_MAX', 'UserDict', 'WCONTINUED', 'WCOREDUMP', 'WEXITSTATUS', 'WIFCONTINUED', 'WIFEXITED', 'WIFSIGNALED', 'WIFSTOPPED', 'WNOHANG', 'WSTOPSIG', 'WTERMSIG', 'WUNTRACED', 'W_OK', 'X_OK', '_Environ', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_copy_reg', '_execvpe', '_exists', '_exit', '_get_exports_list', '_make_stat_result', '_make_statvfs_result', '_pickle_stat_result', '_pickle_statvfs_result', '_spawnvef', 'abort', 'access', 'altsep', 'chdir', 'chmod', 'chown', 'chroot', 'close', 'closerange', 'confstr', 'confstr_names', 'ctermid', 'curdir', 'defpath', 'devnull', 'dup', 'dup2', 'environ', 'errno', 'error', 'execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp', 'execvpe', 'extsep', 'fchdir', 'fchmod', 'fchown', 'fdatasync', 'fdopen', 'fork', 'forkpty', 'fpathconf', 'fstat', 'fstatvfs', 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getegid', 'getenv', 'geteuid', 'getgid', 'getgroups', 'getloadavg', 'getlogin', 'getpgid', 'getpgrp', 'getpid', 'getppid', 'getresgid', 'getresuid', 'getsid', 'getuid', 'initgroups', 'isatty', 'kill', 'killpg', 'lchown', 'linesep', 'link', 'listdir', 'lseek', 'lstat', 'major', 'makedev', 'makedirs', 'minor', 'mkdir', 'mkfifo', 'mknod', 'name', 'nice', 'open', 'openpty', 'pardir', 'path', 'pathconf', 'pathconf_names', 'pathsep', 'pipe', 'popen', 'popen2', 'popen3', 'popen4', 'putenv', 'read', 'readlink', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', 'sep', 'setegid', 'seteuid', 'setgid', 'setgroups', 'setpgid', 'setpgrp', 'setregid', 'setresgid', 'setresuid', 'setreuid', 'setsid', 'setuid', 'spawnl', 'spawnle', 'spawnlp', 'spawnlpe', 'spawnv', 'spawnve', 'spawnvp', 'spawnvpe', 'stat', 'stat_float_times', 'stat_result', 'statvfs', 'statvfs_result', 'strerror', 'symlink', 'sys', 'sysconf', 'sysconf_names', 'system', 'tcgetpgrp', 'tcsetpgrp', 'tempnam', 'times', 'tmpfile', 'tmpnam', 'ttyname', 'umask', 'uname', 'unlink', 'unsetenv', 'urandom', 'utime', 'wait', 'wait3', 'wait4', 'waitpid', 'walk', 'write']
这么多内容不能都介绍,列出来纯粹是要吓唬你一下,先混个脸熟,将来用到哪个了,可以到这里来找。
下面选择几个介绍一番,目的是不断强化我已经常用但是不知道你是否熟悉的学习方法,当然,还有最好的工具——google(内事不决问google,外事不明问谷歌,须梯子)。
操作文件:重命名、删除文件
在对文件进行操作的时候,open()
这个内建函数可以打开文件。但是,如果对文件进行改名、删除操作,就要是用os模块的方法了。
首先建立一个文件,文件名为22201.py,文件内容是:
#!/usr/bin/env python# coding=utf-8print "This is a tmp file."
然后将这个文件名称修改为别的名称。
>>> import os>>> os.rename("22201.py", "newtemp.py")
注意,我是先进入到了文件22201.py的目录,然后进入交互模式,所以,可以直接写文件名,如果不是这样,需要将文件名的路径写上。
os.rename("22201.py", "newtemp.py")
中,第一个文件是原文件名称,第二个是打算修改成为的文件名。
然后查看,能够看到这个文件。
$ ls new*newtemp.py
文件内容可以用cat newtemp.py
看看(这是在ubuntu系统,如果是windows系统,可以用其相应的编辑器打开文件看内容)。
除了修改文件名称,还可以修改目录名称。请注意阅读帮助信息。
Help on built-in function rename in module posix:rename(...) rename(old, new) Rename a file or directory.
另外一个os.remove(),首先看帮助信息,然后再实验。
Help on built-in function remove in module posix:remove(...) remove(path) Remove a file (same as unlink(path)).
为了测试,先建立一些文件。
$ pwd/home/qw/Documents/VBS/StarterLearningPython/2code/rd
这是我建立的临时目录,里面有几个文件:
$ lsa.py b.py c.py
下面删除a.py文件
>>> import os>>> os.remove("/home/qw/Documents/VBS/StarterLearningPython/2code/rd/a.py")
看看删了吗?
$ lsb.py c.py
果然管用呀。再来一个狠的:
>>> os.remove("/home/qw/Documents/VBS/StarterLearningPython/2code/rd")Traceback (most recent call last): File "<stdin>", line 1, in <module>OSError: [Errno 21] Is a directory: '/home/qw/Documents/VBS/StarterLearningPython/2code/rd'
报错了。
我打算将这个目录下的所剩文件删光光,但这么做不行。注意帮助中一句话Remove a file
,os.remove()就是用来删除文件的。并且从报错中也可以看到,错误的原因在于那个参数是一个目录。
要删除目录,还得继续向下学习。
操作目录
os.listdir:显示目录中的内容(包括文件和子目录)。
Help on built-in function listdir in module posix:listdir(...) listdir(path) -> list_of_stringsReturn a list containing the names of the entries in the directory. path: path of directory to listThe list is in arbitrary order. It does not include the specialentries '.' and '..' even if they are present in the directory.
看完帮助信息,读者一定觉得这是一个非常简单的方法,不过,特别注意它返回的值是列表,且不显示目录中某些隐藏文件或子目录。
>>> os.listdir("/home/qw/Documents/VBS/StarterLearningPython/2code/rd")['b.py', 'c.py']>>> files = os.listdir("/home/qw/Documents/VBS/StarterLearningPython/2code/rd")>>> for f in files:... print f... b.pyc.py
os.getcwd:当前工作目录;os.chdir:改变当前工作目录
这两个函数怎么用?唯有通过help()
看文档啦。请读者自行看看。就不贴出来了,仅演示一个例子:
>>> cwd = os.getcwd() #当前目录>>> print cwd/home/qw/Documents/VBS/StarterLearningPython/2code/rd>>> os.chdir(os.pardir) #进入到上一级>>> os.getcwd() #当前'/home/qw/Documents/VBS/StarterLearningPython/2code'>>> os.chdir("rd") #进入下级>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code/rd'
os.pardir
的功能是获得父级目录,相当于..
>>> os.pardir'..'
os.makedirs, os.removedirs:创建和删除目录
直接上例子:
>>> dir = os.getcwd()>>> dir'/home/qw/Documents/VBS/StarterLearningPython/2code/rd'>>> os.removedirs(dir)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/os.py", line 170, in removedirs rmdir(name)OSError: [Errno 39] Directory not empty: '/home/qw/Documents/VBS/StarterLearningPython/2code/rd'
什么时候都不能得意忘形,一定要谦卑,从看文档开始一点一点地理解。看报错信息,要删除某个目录,那个目录必须是空的。
>>> os.getcwd() '/home/qw/Documents/VBS/StarterLearningPython/2code'
这是当前目录,在这个目录下再建一个新的子目录:
>>> os.makedirs("newrd")>>> os.chdir("newrd")>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code/newrd'
建立了一个。下面把刚刚建立的这个目录删除了,毫无疑问它是空的。
>>> os.listdir(os.getcwd())[]>>> newdir = os.getcwd()>>> os.removedirs(newdir)
按照我的理解,这里应该报错。因为我是在当前工作目录删除当前工作目录。如果这样能够执行,总觉得有点别扭。但事实上行得通。就算是Python的规定吧。不过,让我来确定这个功能的话,还是习惯不能在本地删除本地。
按照上面的操作,再看当前的工作目录:
>>> os.getcwd()Traceback (most recent call last): File "<stdin>", line 1, in <module>OSError: [Errno 2] No such file or directory
目录被删了,只能回到父级。
>>> os.chdir(os.pardir)>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code'
有点不可思议,本来没有当前工作目录,怎么会有“父级”的呢?但显示就是这样。
补充一点,前面说的如果目录不空,就不能用os.removedirs()
删除。但是,可以用模块shutil
的retree()
方法。
>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code'>>> os.chdir("rd")>>> now = os.getcwd()>>> now'/home/qw/Documents/VBS/StarterLearningPython/2code/rd'>>> os.listdir(now)['b.py', 'c.py']>>> import shutil>>> shutil.rmtree(now)>>> os.getcwd()Traceback (most recent call last): File "<stdin>", line 1, in <module>OSError: [Errno 2] No such file or directory
请读者注意的是,对于os.makedirs()
还有这样的特点:
>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code'>>> d0 = os.getcwd()>>> d1 = d0+"/ndir1/ndir2/ndir3" #这是想建立的目录,但是中间的ndir1,ndir2也都不存在。>>> d1'/home/qw/Documents/VBS/StarterLearningPython/2code/ndir1/ndir2/ndir3'>>> os.makedirs(d1)>>> os.chdir(d1)>>> os.getcwd()'/home/qw/Documents/VBS/StarterLearningPython/2code/ndir1/ndir2/ndir3'
不存在的目录也被建立起来,直到最右边的目录为止。与os.makedirs()
类似的还有os.mkdir()
,不过,os.mkdir()
没有上面这个功能,它只能一层一层地建目录。os.removedirs()
和os.rmdir()
也类似,区别也类似上面。
文件和目录属性
不管是哪种操作系统,都能看到文件或者目录的有关属性,那么,在os模块中,也有这样的一个方法:os.stat()
>>> p = os.getcwd() #当前目录>>> p'/home/qw/Documents/VBS/StarterLearningPython'
显示这个目录的有关信息:
>>> os.stat(p)posix.stat_result(st_mode=16895, st_ino=4L, st_dev=26L, st_nlink=1, st_uid=0, st_gid=0, st_size=12288L, st_atime=1430224935, st_mtime=1430224935, st_ctime=1430224935)
再指定一个文件:
>>> pf = p + "/README.md"
显示此文件的信息:
>>> os.stat(pf)posix.stat_result(st_mode=33279, st_ino=67L, st_dev=26L, st_nlink=1, st_uid=0, st_gid=0, st_size=50L, st_atime=1429580969, st_mtime=1429580969, st_ctime=1429580969)
从结果中看,可能看不出什么来,先不用着急。这样的结果是对computer姑娘是友好的,但对读者可能不友好。如果用下面的方法,就友好多了:
>>> fi = os.stat(pf)>>> mt = fi[8]
fi[8]
就是st_mtime
的值,它代表最后modified(修改)文件的时间。看结果:
>>> mt1429580969
还是不友好,下面就用time
模块来友好一下:
>>> import time>>> time.ctime(mt)'Tue Apr 21 09:49:29 2015'
现在就对读者友好了。
用os.stat()
能够查看文件或者目录的属性。如果要修改呢?比如在部署网站的时候,常常要修改目录或者文件的权限等。这种操作在Python的os
模块能做到吗?
要求越来越多了。在一般情况下,不在Python里做这个,当然,世界是复杂的,肯定有人会用到的,所以os
模块提供了os.chmod()
。
操作命令
读者如果使用某种Linux系统,或者曾经用过DOS(恐怕很少),或者在Windows里面用过command,对敲命令都不陌生。通过命令来做事情的确是很酷的。比如,我是在Ubuntu中,要查看文件和目录,只需要ls
就足够了。我并不是否认图形界面,对于某些人(比如程序员)在某些情况下,命令是不错的选项,甚至是离不开的。
os
模块中提供了这样的方法,许可程序员在Python程序中使用操作系统的命令。(以下是在Ubuntu系统,如果读者是Windows,可以将命令换成DOS命令。)
>>> p'/home/qw/Documents/VBS/StarterLearningPython'>>> command = "ls " + p>>> command'ls /home/qw/Documents/VBS/StarterLearningPython'
为了输入方便,采用了前面例子中已经有的那个目录,并且,用拼接字符串的方式,将要输入的命令(查看某文件夹下的内容)组装成一个字符串,赋值给变量command,然后:
>>> os.system(command)01.md 101.md 105.md 109.md 113.md 117.md 121.md 125.md 129.md 201.md 205.md 209.md 213.md 217.md 221.md https://normanbb.gitbooks.io/test/content/index.md02.md 102.md 106.md 110.md 114.md 118.md 122.md 126.md 130.md 202.md 206.md 210.md 214.md 218.md 222.md n001.md03.md 103.md 107.md 111.md 115.md 119.md 123.md 127.md 1code 203.md 207.md 211.md 215.md 219.md 2code README.md0images 104.md 108.md 112.md 116.md 120.md 124.md 128.md 1images 204.md 208.md 212.md 216.md 220.md 2images0
这样就列出来了该目录下的所有内容。
需要注意的是,os.system()
是在当前进程中执行命令,直到它执行结束。如果需要一个新的进程,可以使用os.exec
或者os.execvp
。对此有兴趣详细了解的读者,可以查看帮助文档了解。另外,os.system()
是通过shell执行命令,执行结束后将控制权返回到原来的进程,但是os.exec()
及相关的函数,则在执行后不将控制权返回到原继承,从而使Python失去控制。
关于Python对进程的管理,此处暂不过多介绍,读者可以查阅有关专门资料。
os.system()
是一个用途很多的方法。曾有一个朋友网上询问,用它来启动浏览器。不过,这个操作的确要非常仔细。为什么呢?演示一下就明白了。
>>> os.system("/usr/bin/firefox")(process:4002): GLib-CRITICAL **: g_slice_set_config: assertion 'sys_page_size == 0' failed(firefox:4002): GLib-GObject-WARNING **: Attempt to add property GnomeProgram::sm-connect after class was initialised......
我是在Ubuntu上操作的,浏览器的地址是/usr/bin/firefox
,可是,那个朋友是Windows系统,那么就要非常小心了,因为在Windows里面,表示路径的斜杠是跟上面显示的是反着的,可是在Python中\
代表转义。比较简单的一个方法是用r"c:\user\firfox.exe"
的样式,因为在r" "
中的,都被认为是原始字符。而且Windows系统中,一般情况下那个文件不是安装在我演示的那个简单样式的文件夹中,而是C:\Program Files
,这中间还有空格,所以还要注意空格问题。读者按照这些提示,看看能不能完成用os.system()
启动firefox的操作。
凡事感觉麻烦的东西,必然有另外简单的来替代。于是又有了一个webbrowser
模块。可以专门用来打开指定网页。
>>> import webbrowser>>> webbrowser.open("http://www.itdiffer.com")True
不管是什么操作系统,只要如上操作就能打开网页。
真是神奇的标准库,有如此多的工具,能不加速开发进程吗?能不降低开发成本吗?“人生苦短,我用python”!