標(biāo)準(zhǔn)庫(kù)(3)

2018-02-24 15:48 更新

OS

os模塊提供了訪問(wèn)操作系統(tǒng)服務(wù)的功能,它所包含的內(nèi)容比較多。

>>> 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']

這么多內(nèi)容不能都介紹,況且不少方法在實(shí)踐中用的不多,比如os.popen()在實(shí)踐中用到了,但是os模塊還有popen2、popen3、popen4,這三個(gè)我在實(shí)踐中都沒有用過(guò),或者有別人用了,也請(qǐng)補(bǔ)充。不過(guò),我下面介紹的都是自認(rèn)為用的比較多的,至少是我用的比較多或者用過(guò)的。如果沒有讀者要是用,但是我這里沒有介紹,讀者也完全可以自己用我們常用的help()來(lái)自學(xué)明白其應(yīng)用方法,當(dāng)然,還有最好的工具——google(內(nèi)事不決問(wèn)google,外事不明問(wèn)谷歌,須梯子)。

操作文件:重命名、刪除文件

在對(duì)文件操作的時(shí)候,open()這個(gè)內(nèi)建函數(shù)可以建立、打開文件。但是,如果對(duì)文件進(jìn)行改名、刪除操作,就要是用os模塊的方法了。

首先建立一個(gè)文件,文件名為22201.py,文件內(nèi)容是:

#!/usr/bin/env python
# coding=utf-8

print "This is a tmp file."

然后將這個(gè)文件名稱修改為其它的名稱。

>>> import os
>>> os.rename("22201.py", "newtemp.py")

注意,我是先進(jìn)入到了文件22201.py的目錄,然后進(jìn)入到python交互模式,所以,可以直接寫文件名,如果不是這樣,需要將文件名的路徑寫上。os.rename("22201.py", "newtemp.py")中,第一個(gè)文件是原文件名稱,第二個(gè)是打算修改成為的文件名。

$ ls new*
newtemp.py

查看,能夠看到這個(gè)文件。并且文件內(nèi)容可以用cat newtemp.py看看(這是在ubuntu系統(tǒng),如果是windows系統(tǒng),可以用其相應(yīng)的編輯器打開文件看內(nèi)容)。

Help on built-in function rename in module posix:

rename(...)
    rename(old, new)

    Rename a file or directory.

除了修改文件名稱,還可以修改目錄名稱。請(qǐng)注意閱讀幫助信息。

另外一個(gè)os.remove(),首先看幫助信息,然后再實(shí)驗(yàn)。

Help on built-in function remove in module posix:

remove(...)
    remove(path)

    Remove a file (same as unlink(path)).

比較簡(jiǎn)單。那就測(cè)試一下。為了測(cè)試,先建立一些文件吧。

$ pwd
/home/qw/Documents/VBS/StarterLearningPython/2code/rd

這是我建立的臨時(shí)目錄,里面有幾個(gè)文件:

$ ls
a.py  b.py  c.py

下面刪除a.py文件

>>> import os
>>> os.remove("/home/qw/Documents/VBS/StarterLearningPython/2code/rd/a.py")

看看刪了嗎?

$ ls
b.py  c.py

果然管用呀。再來(lái)一個(gè)狠的:

>>> 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'

報(bào)錯(cuò)了。我打算將這個(gè)目錄下的所剩文件刪光光。這么做不行。注意幫助中一句話Remove a file,os.remove()就是用來(lái)刪除文件的。并且從報(bào)錯(cuò)中也可以看到,告訴我們錯(cuò)誤的原因在于那個(gè)參數(shù)是一個(gè)目錄。

要?jiǎng)h除目錄,還得繼續(xù)向下學(xué)習(xí)。

操作目錄

os.listdir:顯示目錄中的文件

Help on built-in function listdir in module posix:

listdir(...)
    listdir(path) -> list_of_strings

Return a list containing the names of the entries in the directory.

    path: path of directory to list

The list is in arbitrary order.  It does not include the special
entries '.' and '..' even if they are present in the directory.

看完幫助信息,讀者一定覺得這是一個(gè)非常簡(jiǎn)單的方法,不過(guò),特別注意它返回的值是列表,還有就是如果文件夾中有那樣的特殊格式命名的文件,不顯示。在linux中,用ls命令也看不到這些隱藏的東東。

>>> 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.py
c.py

os.getcwd, os.chdir:當(dāng)前工作目錄,改變當(dāng)前工作目錄

這兩個(gè)函數(shù)怎么用?惟有通過(guò)help()看文檔啦。請(qǐng)讀者自行看看。我就不貼出來(lái)了,僅演示一個(gè)例子:

>>> cwd = os.getcwd()     #當(dāng)前目錄
>>> print cwd
/home/qw/Documents/VBS/StarterLearningPython/2code/rd
>>> os.chdir(os.pardir)    #進(jìn)入到上一級(jí)

>>> os.getcwd()            #當(dāng)前
'/home/qw/Documents/VBS/StarterLearningPython/2code'

>>> os.chdir("rd")         #進(jìn)入下級(jí)

>>> os.getcwd()
'/home/qw/Documents/VBS/StarterLearningPython/2code/rd'

os.pardir的功能是獲得父級(jí)目錄,相當(dāng)于..

>>> os.pardir
'..'

os.makedirs, os.removedirs:創(chuàng)建和刪除目錄

廢話少說(shuō),路子還是前面那樣,就省略看幫助了,讀者可以自己看。直接上例子:

>>> 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'

什么時(shí)候都不能得意忘形,一定要謙卑。那就是從看文檔開始一點(diǎn)一點(diǎn)地理解。不能像上面那樣,自以為是、貿(mào)然行事??磮?bào)錯(cuò)信息,要?jiǎng)h除某個(gè)目錄,那個(gè)目錄必須是空的。

>>> os.getcwd()                   
'/home/qw/Documents/VBS/StarterLearningPython/2code'

這是當(dāng)前目錄,在這個(gè)目錄下再建一個(gè)新的子目錄:

>>> os.makedirs("newrd")
>>> os.chdir("newrd")
>>> os.getcwd()
'/home/qw/Documents/VBS/StarterLearningPython/2code/newrd'

建立了一個(gè)。下面把這個(gè)刪除了。這個(gè)是空的。

>>> os.listdir(os.getcwd())
[]
>>> newdir = os.getcwd()
>>> os.removedirs(newdir)

按照我的理解,這里應(yīng)該報(bào)錯(cuò)。因?yàn)槲沂窃诋?dāng)前工作目錄刪除當(dāng)前工作目錄。如果這樣能夠執(zhí)行,總覺得有點(diǎn)別扭。但事實(shí)上,就行得通了。就算是python的規(guī)定吧。不過(guò),讓我來(lái)確定這個(gè)功能的話,還是習(xí)慣不能在本地刪除本地。

按照上面的操作,在看當(dāng)前工作目錄:

>>> os.getcwd()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory

目錄被刪了,當(dāng)然沒有啦。只能回到父級(jí)。

>>> os.chdir(os.pardir)
>>> os.getcwd()
'/home/qw/Documents/VBS/StarterLearningPython/2code'

有點(diǎn)不可思議。本來(lái)沒有當(dāng)前工作目錄,怎么會(huì)有“父級(jí)”的呢?但python就是這樣。

補(bǔ)充一點(diǎn),前面說(shuō)的如果目錄不空,就不能用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

請(qǐng)讀者注意的是,對(duì)于os.makedirs()還有這樣的特點(diǎn):

>>> 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'

中間不存在的目錄也被建立起來(lái),直到做右邊的目錄為止。與os.makedirs()類似的還有os.mkdir(),不過(guò),os.mkdir()沒有上面這個(gè)功能,它只能一層一層地建目錄。

os.removedirs()os.rmdir()也類似,區(qū)別也類似上面。

文件和目錄屬性

不管是在什么操作系統(tǒng),都能看到文件或者目錄的有關(guān)屬性,那么,在os模塊中,也有這樣的一個(gè)方法:os.stat()

>>> p = os.getcwd()    #當(dāng)前目錄
>>> p
'/home/qw/Documents/VBS/StarterLearningPython'

#這個(gè)目錄的有關(guān)信息
>>> 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)

#指定一個(gè)文件
>>> 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)

從結(jié)果中看,可能看不出什么來(lái),先不用著急。這樣的結(jié)果是對(duì)computer姑娘友好的,對(duì)讀者可能不友好。如果用下面的方法,就友好多了:

>>> fi = os.stat(pf)
>>> mt = fi[8]

fi[8]就是st_mtime的值,它代表最后modified(修改)文件的時(shí)間??唇Y(jié)果:

>>> mt
1429580969

還是不友好。下面就用time模塊來(lái)友好一下:

>>> import time
>>> time.ctime(mt)
'Tue Apr 21 09:49:29 2015'

現(xiàn)在就對(duì)讀者友好了。

os.stat()能夠查看文件或者目錄的屬性。如果要修改呢?比如在部署網(wǎng)站的時(shí)候,常常要修改目錄或者文件的權(quán)限等。這種操作在python的os模塊能做到嗎?

要求越來(lái)越多了。在一般情況下,不在python里做這個(gè)呀。當(dāng)然,世界是復(fù)雜的。肯定有人會(huì)用到的,所以os模塊提供了os.chmod()

操作命令

讀者如果使用某種linux系統(tǒng),或者曾經(jīng)用過(guò)dos(恐怕很少),或者再windows里面用過(guò)command,對(duì)敲命令都不陌生。通過(guò)命令來(lái)做事情的確是很酷的。比如,我是在ubuntu中,要查看文件和目錄,只需要ls就足夠了。我并不是否認(rèn)圖形界面,而是在某些情況下,還是離不開命令的,比如用程序來(lái)完成查看文件和目錄的操作。所以,os模塊中提供了這樣的方法,許可程序員在python程序中使用操作系統(tǒng)的命令。(以下是在ubuntu系統(tǒng),如果讀者是windows,可以將命令換成DOS命令。)

>>> p
'/home/qw/Documents/VBS/StarterLearningPython'
>>> command = "ls " + p
>>> command
'ls /home/qw/Documents/VBS/StarterLearningPython'

為了輸入方便,我采用了前面例子中已經(jīng)有的那個(gè)目錄,并且,用拼接字符串的方式,將要輸入的命令(查看某文件夾下的內(nèi)容)組裝成一個(gè)字符串,賦值給變量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   index.md
02.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.md
03.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.md
0images  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  2images
0

這樣就列出來(lái)了該目錄下的所有內(nèi)容。

需要注意的是,os.system()是在當(dāng)前進(jìn)程中執(zhí)行命令,直到它執(zhí)行結(jié)束。如果需要一個(gè)新的進(jìn)程,可以使用os.exec或者os.execvp。對(duì)此有興趣詳細(xì)了解的讀者,可以查看幫助文檔了解。另外,os.system()是通過(guò)shell執(zhí)行命令,執(zhí)行結(jié)束后將控制權(quán)返回到原來(lái)的進(jìn)程,但是os.exec()及相關(guān)的函數(shù),則在執(zhí)行后不將控制權(quán)返回到原繼承,從而使python失去控制。

關(guān)于python對(duì)進(jìn)程的管理,此處暫不過(guò)多介紹。

os.system()是一個(gè)用途不少的函數(shù)。曾有一個(gè)朋友網(wǎng)上詢問(wèn),用它來(lái)啟動(dòng)瀏覽器。不過(guò),這個(gè)操作的確要非常仔細(xì)。為什么呢?演示一下就明白了。

>>> 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,可是,那個(gè)朋友是windows,他就要非常小心了,因?yàn)樵趙indows里面,表示路徑的斜杠是跟上面顯示的是反著的,可是在python中\這種斜杠代表轉(zhuǎn)義。解決這個(gè)問(wèn)題可以參看《字符串(1)》的轉(zhuǎn)義符以及《字符串(2)》的原始字符串講述。比較簡(jiǎn)單的一個(gè)方法用r"c:\user\firfox.exe"的樣式,因?yàn)樵?code>r" "中的,都是被認(rèn)為原始字符了。還沒完,因?yàn)閣indows系統(tǒng)中,一般情況下那個(gè)文件不是安裝在我演示的那個(gè)簡(jiǎn)單樣式的文件夾中,而是C:\Program Files,這中間還有空格,所以還要注意,空格問(wèn)題。簡(jiǎn)直有點(diǎn)暈頭轉(zhuǎn)向了。讀者按照這些提示,看看能不能完成用os.system()啟動(dòng)firefox的操作呢?

凡事感覺麻煩的東西,必然有另外簡(jiǎn)單的來(lái)替代。于是又有了一個(gè)webbrowser模塊??梢詫iT用來(lái)打開指定網(wǎng)頁(yè)。

>>> import webbrowser
>>> webbrowser.open("http://www.itdiffer.com")
True

不管是什么操作系統(tǒng),只要如上操作就能打開網(wǎng)頁(yè)了。

真是神奇的標(biāo)準(zhǔn)庫(kù),有如此多的工具,能不加速開發(fā)進(jìn)程嗎?能不降低開發(fā)成本嗎?“人生苦短,我用python”!

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)