標準庫:一些最愛
sys
sys這個模塊讓你能夠訪問與python解釋器聯繫緊密的變量和函數。
sys模塊中一些重要的函數和變量
函數/變量 描述
argv 命令行參數,包括腳本名稱
exit([arg]) 退出當前程序,可選參數爲給定的返回值或者錯誤信息
modules 映射模塊名字到載入模塊的字典
path 查找模塊所在目錄的目錄名列表
platform 類似sunos5或者win32的平臺標識符
stdin 標準輸入流——一個類文件對象
stdout 標準輸出流——一個類文件對象
stderr 標準錯誤流——一個類文件對象
變量sys.argv包括傳遞到python解釋器的參數,包括腳本名稱;
函數sys.exit可以退出當前程序(如果在try/finally塊中調用,finally子句的內容仍然會被執行)。可以提供一個整數參數,用來標識程序是否成功運行——unix的一個慣例。大多數情況下使用該整數的默認值就可以了(也就是0,表示成功)。或者也可以提供字符串參數,用作錯誤信息,這對於用戶找出程序停止運行的原因會很有用。這樣,程序就會在退出的時候提供錯誤信息和標識程序運行失敗的代碼。
映射sys.modules將模塊名映射到實際存在的模塊上,它只應用於目前導入的模塊。
sys.path是一個字符串列表,其中的每個字符串都是一個目錄名,在import語句執行時,解釋器就會從這些目錄中查找模塊。
sys.platform模塊變量是解釋器正在其上運行的“平臺”名稱。可能是操作系統的名字,也可能是標識其他種類的平臺,如果你運行Jython的話,就是java虛擬機。
sys.stdin、sys.stdout、sys.stderr模塊變量是類文件流對象。它們表示標準UNIX概念中的標準輸入、標準輸出和標準錯誤。
練習 處理命令行參數
當通過命令行調用python腳本時,可能會在後面加上一些參數——它們就是命令行參數。這些參數會放置在sys.argv列表中,腳本的名字爲sys.argv[0]。
$ cat reverseargs.py
#!/usr/bin/python
import sys
args=sys.argv[1:]
args.reverse()
print ' '.join(args)
$ ./reverseargs.py 1 3 4
4 3 1
$ ./reverseargs.py 1 3 "ab" [2,4,'6']
6 4 2 ab 3 1
獲取腳本參數
腳本內容
$ cat sys-argv-example-1.py
# File:sys-argv-example-1.py
import sys
print "Script name is",sys.argv[0]
if len(sys.argv) > 1:
print "there is",len(sys.argv)-1,"arguments:"
print [x for x in sys.argv[1:]]
else:
print "there are no arguments!"
執行結果
$ python sys-argv-example-1.py
Script name is sys-argv-example-1.py
there are no arguments!
$ python sys-argv-example-1.py 'a' 2 'c' 'four'
Script name is sys-argv-example-1.py
there is 4 arguments:
['a', '2', 'c', 'four']
如果從標準輸入讀取腳本(如”python < sys-argv-example-1.py”),腳本名稱將被設置爲空字符串。如果把腳本作爲字符串傳遞給python(使用-c參數),則腳本名稱被設置爲“-c”。
$ python < sys-argv-example-1.py
Script name is
there are no arguments!
練習 處理模塊
操作模塊的路徑
腳本內容
$ cat sys-path-example-1.py
#File:sys-path-example-1.py
import sys
print "path has",len(sys.path),"members"
print sys.path
#add the sample directory to the path
sys.path.insert(0,"samples")
print "path has",len(sys.path),"members"
print sys.path
import sample
#nuke the path
sys.path=[]
import random # oops!
執行結果
path has 10 members
['/home/ggz2/magiccube/mysh/pys', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib/python2.6/site-packages']
path has 11 members
['samples', '/home/ggz2/magiccube/mysh/pys', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib/python2.6/site-packages']
Traceback (most recent call last):
File "sys-path-example-1.py", line 12, in <module>
import sample
ImportError: No module named sample
查找內建模塊
腳本內容
$ cat sys-builtin-module-names-example-1.py
# File :sys-builtin-module-names-example-1.py
import sys
def dump(module):
print module,"=>",
if module in sys.builtin_module_names:
print "<BUILTIN>"
else:
module = __import__(module)
print module.__file__
dump("os")
dump("sys")
dump("string")
dump("strop")
dump("zlib")
執行結果
$ python sys-builtin-module-names-example-1.py
os => /usr/lib64/python2.6/os.pyc
sys => <BUILTIN>
string => /usr/lib64/python2.6/string.pyc
strop => /usr/lib64/python2.6/lib-dynload/stropmodule.so
zlib => /usr/lib64/python2.6/lib-dynload/zlibmodule.so
查找導入的模塊
腳本內容
$ cat sys-modules-example-1.py
#File:sys-modules-example-1.py
import sys
print sys.modules.keys()
執行結果
$ python sys-modules-example-1.py
['copy_reg', 'encodings', 'site', '__builtin__', '__main__', 'encodings.encodings', 'abc', 'posixpath', 'errno', 'encodings.codecs', '_abcoll', 'types', '_codecs', '_warnings', 'genericpath', 'stat', 'zipimport', 'encodings.__builtin__', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'codecs', 'os.path', 'signal', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'os']
練習 引用計數
獲得引用數量
getrefcount函數返回給定對象的引用數量,即變量被引用的數量。python追蹤這些變量,當引用數爲0時,對象被銷燬。
腳本內容
$ cat sys-getrefcount-example-1.py
#File:sys-getrefcount-example-1.py
import sys
variable=1234
print sys.getrefcount(0)
print sys.getrefcount(variable)
print sys.getrefcount(None)
執行結果
$ python sys-getrefcount-example-1.py
147
4
700
注意:這個值總是比實際的值要大些,因爲當確定值時函數本身依賴這個對象。
練習 主機平臺
腳本內容
$ cat sys-platform-example-1.py
#File:sys-platform-example-1.py
import sys
#
# emulate "import os.path" (sort of)...
if sys.platform == "win32":
import ntpath
pathmodule=ntpath
elif sys.platform == "mac":
import macpath
pathmodule=macpath
else:
# assume it's a posix platform
import posixpath
pathmodule=posixpath
print pathmodule
執行結果
centos 5.4系統下執行:
$ python sys-platform-example-1.py
<module 'posixpath' from '/usr/lib64/python2.6/posixpath.pyc'>
Win7系統下執行:
<module 'ntpath' from 'D:\software(x86)\Python27\lib\ntpath.pyc'>
典型的平臺名稱爲win32(Windows 9x/NT平臺)和mac(Macintosh平臺)。Unix操作系統,平臺名稱通常由命令“uname -r”命令導出,比如irix6,linux2,或者sunos5(Solaris)。
$ uname -r
2.6.32-358.el6.x86_64
練習 追蹤程序
setprofiler函數允許你配置一個配置函數。每當一個函數或方法被調用,每一次返回(隱式或顯式),每一次異常時被調用。
腳本內容
$ cat sys-setprofiler-example-1.py
#File:sys-setprofiler-example-1.py
import sys
def test(n):
j=0
for i in range(n):
j=j+i
return n
def profiler(frame,event,arg):
print event,frame.f_code.co_name,frame.f_lineno,"->",arg
# profiler is activated on the next call,return,or exception
sys.setprofile(profiler)
# profile this function call
test(1)
# disable profiler
sys.setprofile(None)
# don't profile this call
test(2)
執行結果
$ python sys-setprofiler-example-1.py
call test 5 -> None
c_call test 7 -> <built-in function range>
c_return test 7 -> <built-in function range>
return test 9 -> 1
c_call <module> 21 -> <built-in function setprofile>
基於該函數,profile模塊提供了完整的分析器框架。
settrace函數與此類似,但trace函數在解釋器執行新行的時候被調用。
腳本內容
$ cat sys-settrace-example-1.py
#File:sys-settrace-example-1.py
import sys
def test(n):
j=0
for i in range(n):
j=j+1
return n
def tracer(frame,event,arg):
print event,frame.f_code.co_name,frame.f_lineno,"->",arg
return tracer
#trace is activated on the next call,return,or exception
sys.settrace(tracer)
#trace this function call
test(1)
# disable tracing
sys.settrace(None)
# don't trace this call
test(2)
執行結果
$ python sys-settrace-example-1.py
call test 5 -> None
line test 6 -> None
line test 7 -> None
line test 8 -> None
line test 7 -> None
line test 9 -> None
return test 9 -> 1
基於該函數提供的跟蹤功能,pdb模塊提供了一個完整的調試器框架。
練習 操作標準輸入輸出
stdin、stdout、stderr變量包含與標準輸入輸出流相對應的流對象。如果需要提供比print更好地控制輸出可以直接訪問它們。如果你想重定向輸入和輸出到其它設備也可以替換它們,或者以某種非標準方式處理它們。
重定向輸出
腳本內容
$ cat sys-stdout-example-1.py
#File:sys-stdout-example-1.py
import sys
import string
class Redirect:
def __init__(self,stdout):
self.stdout=stdout
def write(self,s):
self.stdout.write(string.lower(s))
# redirect standard output(including the print statement)
old_stdout=sys.stdout
sys.stdout=Redirect(sys.stdout)
print "HEJA SVERIGE",
print "FRISKT HUM\303\226R"
# restore standard output
sys.stdout=old_stdout
print "M\303\205\303\205\303\205\303\205L!"
執行結果
$ python sys-stdout-example-1.py
heja sverige friskt humÖr
MÅÅÅÅL!
練習 退出程序
當到達主程序的末尾時,解釋器自動終止。如果需要中途退出,可以調用sys.exit函數,它能給調用它的程序返回一個可配置的整數。
退出程序
腳本內容
$ cat sys-exit-example-1.py
#File :sys-exit-example-1.py
import sys
print "Hello"
sys.exit(1)
print "there"
執行結果
$ python sys-exit-example-1.py
Hello
注意:sys.exit不是立即退出的,相反地,它引發了一個SystemExit異常。
捕獲調用sys.exit
腳本內容
$ cat sys-exit-example-2.py
#File :sys-exit-example-2.py
import sys
print "Hello"
try:
sys.exit(1)
except SystemExit:
pass
print "there"
執行結果
$ python sys-exit-example-2.py
Hello
there
如果你想在你之後清空一些內容,可以設置exit handle,它是一個在退出時自動調用的函數。
用另一種方式捕獲調用sys.exit
腳本內容
$ cat sys-exitfunc-example-1.py
#File:sys-exitfunc-example-1.py
import sys
def exitfunc():
print "world"
sys.exitfunc=exitfunc
print "hello"
sys.exit(1)
print "there" # never printed
執行結果
$ python sys-exitfunc-example-1.py
hello
world