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

2018-02-24 15:48 更新

OS

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

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

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

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

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

print "This is a tmp file."

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

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

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

$ ls new*
newtemp.py

查看,能夠看到這個文件。并且文件內(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.

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

另外一個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

這是我建立的臨時目錄,里面有幾個文件:

$ 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

果然管用呀。再來一個狠的:

>>> 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()就是用來刪除文件的。并且從報錯中也可以看到,告訴我們錯誤的原因在于那個參數(shù)是一個目錄。

要刪除目錄,還得繼續(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.

看完幫助信息,讀者一定覺得這是一個非常簡單的方法,不過,特別注意它返回的值是列表,還有就是如果文件夾中有那樣的特殊格式命名的文件,不顯示。在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)前工作目錄

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

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

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

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

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

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

>>> os.pardir
'..'

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

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

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

什么時候都不能得意忘形,一定要謙卑。那就是從看文檔開始一點一點地理解。不能像上面那樣,自以為是、貿(mào)然行事。看報錯信息,要刪除某個目錄,那個目錄必須是空的。

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

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

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

按照我的理解,這里應(yīng)該報錯。因為我是在當(dāng)前工作目錄刪除當(dāng)前工作目錄。如果這樣能夠執(zhí)行,總覺得有點別扭。但事實上,就行得通了。就算是python的規(guī)定吧。不過,讓我來確定這個功能的話,還是習(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)然沒有啦。只能回到父級。

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

有點不可思議。本來沒有當(dāng)前工作目錄,怎么會有“父級”的呢?但python就是這樣。

補(bǔ)充一點,前面說的如果目錄不空,就不能用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()也類似,區(qū)別也類似上面。

文件和目錄屬性

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

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

#這個目錄的有關(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)

#指定一個文件
>>> 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é)果中看,可能看不出什么來,先不用著急。這樣的結(jié)果是對computer姑娘友好的,對讀者可能不友好。如果用下面的方法,就友好多了:

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

fi[8]就是st_mtime的值,它代表最后modified(修改)文件的時間。看結(jié)果:

>>> mt
1429580969

還是不友好。下面就用time模塊來友好一下:

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

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

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

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

操作命令

讀者如果使用某種linux系統(tǒng),或者曾經(jīng)用過dos(恐怕很少),或者再windows里面用過command,對敲命令都不陌生。通過命令來做事情的確是很酷的。比如,我是在ubuntu中,要查看文件和目錄,只需要ls就足夠了。我并不是否認(rèn)圖形界面,而是在某些情況下,還是離不開命令的,比如用程序來完成查看文件和目錄的操作。所以,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)有的那個目錄,并且,用拼接字符串的方式,將要輸入的命令(查看某文件夾下的內(nèi)容)組裝成一個字符串,賦值給變量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

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

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

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

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

凡事感覺麻煩的東西,必然有另外簡單的來替代。于是又有了一個webbrowser模塊。可以專門用來打開指定網(wǎng)頁。

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

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

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號