1. 程式人生 > >Python sys模組(進階篇)

Python sys模組(進階篇)

本文針對原文做了少量修改和大量的補充。。。

這篇文章主要介紹了Python標準庫之sys模組使用詳解,講解了使用sys模組獲得指令碼的引數、處理模組、
使用sys模組操作 模組搜尋路徑、使用sys模組查詢內建模組、使用sys模組查詢已匯入的模組,重定向輸出以及重定向錯誤等使用案例。。。
sys模組提供了許多函式和變數來處理 Python 執行時環境的不同部分.
處理命令列引數:在直譯器啟動後, argv 列表包含了傳遞給指令碼的所有引數, 列表的第一個元素為指令碼自身的名稱.
【1】使用sys模組獲得指令碼的引數(給程式在外部傳遞引數):

test.py檔案:

#!usr/bin/env python
#coding:utf-8
import sys
print 'sys.argv=',sys.argv
print 'The script name is',sys.argv[0] #使用sys.argv[0]採集指令碼名稱
if len(sys.argv)>1:
    print 'There are',len(sys.argv)-1,'arguments!' #使用len(sys.argv)-1採集引數個數,-1為減去[0]指令碼名稱
    for arg in sys.argv[1:]:  #輸出除了[0]外所有引數
        print arg
else:
    print 'There is no argument!'

執行結果:
[email protected]:~$ python test.py
sys.argv= ['test.py']
The script name is test.py
There is no argument!
[email protected]:~$ python test.py argument1 argument2
sys.argv= ['test.py', 'argument1', 'argument2']
The script name is test.py
There are 2 arguments!
argument1
argument2
[email protected]
:~$

【2】如果是從標準輸入讀入指令碼, 指令碼的名稱將被設定為空串。
[email protected]:~$ python < test.py
sys.argv= ['']
The script name is 
There is no argument!

【3】如果把指令碼作為字串傳遞給python (在命令列下選用 -c 選項), 指令碼名會被設定為 "-c"。
[email protected]:~$ python  -c "import sys;print sys.argv;print sys.argv[0]" arg1 arg2
['-c', 'arg1', 'arg2']
-c

[email protected]:~$
如果大家不明白,可以參考下man python
SYNOPSIS
       python [ -d ] [ -E ] [ -h ] [ -i ] [ -m module-name ] [ -O ]
              [ -Q argument ] [ -S ] [ -t ] [ -u ]
              [ -v ] [ -V ] [ -W argument ] [ -x ]
              [ -c command | script | - ] [ arguments ]

處理模組:
我們在使用模組的某一個功能前,需要用import,__import__命令匯入。
那我們在執行import module_name的時候,python內部發生了什麼呢?
簡單的說,就是搜尋module_name。根據sys.path的路徑來搜尋module.name

>>> import sys
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
>>>
我們以後寫好的模組就可以放到上面的某一個目錄下,便可以正確搜尋到了。

當然也可以新增自己的模組路徑。sys.path.append(“my module path”)。

>>> sys.path.append('my module path')
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', 'my module path']
>>> 

path列表是一個由目錄名構成的列表, Python 從中查詢擴充套件模組( Python 源模組, 編譯模組,或者二進位制擴充套件).
啟動 Python 時,這個列表根據內建規則, PYTHONPATH 環境變數的內容, 以及登錄檔( Windows 系統)等進行初始化.
由於它只是一個普通的列表, 你可以在程式中對它進行操作。。。

【4】操作sys模組中的搜尋路徑:

path.py檔案:

#!usr/bin/env python
#coding:utf-8
import sys
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
sys.path.insert(0,'/tmp')  #將路徑插入到path[0]中
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
sys.path=[]  #刪除path中所有路徑
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
#上述對sys.path的修改,僅僅在當前檔案中有效,並不會修改python標準庫中的sys模組。。。
執行結果:
[email protected]:~$ python path.py
sys.path= ['/home/song', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
sys.path has 12 members.
sys.path= ['/tmp', '/home/song', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
sys.path has 13 members.
sys.path= []
sys.path has 0 members.

【5】使用sys模組查詢內建模組:
builtin_module_names 元組包含 Python 直譯器中所有內建模組的名稱

find_module.py檔案:

def find_module(module):
    print module,'=>',
    if module in sys.builtin_module_names: #查詢內建模組是否存在
        print '<biultin>'
    else:
        mod=__import__(module) #非內建模組 輸出模組路徑
        print mod.__file__

import sys
print 'sys.builtin_module_names=',sys.builtin_module_names
find_module('os')
find_module('sys')
find_module('string')
find_module('strop')
find_module('zlib')
執行結果:
[email protected]:~$ python find_module.py
sys.builtin_module_names= ('__builtin__', '__main__', '_ast', '_bisect', '_codecs', '_collections', '_functools', '_heapq', '_io', '_locale', '_md5', '_random', '_sha', '_sha256', '_sha512', '_socket', '_sre', '_struct', '_symtable', '_warnings', '_weakref', 'array', 'binascii', 'cPickle', 'cStringIO', 'cmath', 'errno', 'exceptions', 'fcntl', 'gc', 'grp', 'imp', 'itertools', 'marshal', 'math', 'operator', 'posix', 'pwd', 'select', 'signal', 'spwd', 'strop', 'sys', 'syslog', 'thread', 'time', 'unicodedata', 'xxsubtype', 'zipimport', 'zlib')
os => /usr/lib/python2.7/os.pyc
sys => <biultin>
string => /usr/lib/python2.7/string.pyc
strop => <biultin>
zlib => <biultin>
[email protected]:~$

【6】使用sys模組查詢已匯入的模組(sys.modules):
This is a dictionary that maps module names to modules which have already been loaded.
This can be manipulated to force reloading of modules and other tricks.
Python.org手冊裡已經說的很明白了。
modules 字典包含所有載入的模組。 import 語句在從磁碟匯入內容之前會先檢查這個字典。
Python 在處理你的指令碼之前就已經匯入了很多模組.

>>> import sys
>>> type(sys.modules)
<type 'dict'>
>>> sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings',
 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 
'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 
'encodings.utf_8', 'sys', 'codecs', 'readline', '_sysconfigdata_nd', 'os.path', 'sitecustomize', 'signal', 'traceback',
 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> len(sys.modules.keys())
43
>>>
【7】使用sys模組獲得當前平臺:
sys.platform  返回當前平臺,例如: "win32" "linux2" 等
# windows下:
>>> import sys
>>> sys.platform
'win32'
# Linux下:
>>> import sys
>>> sys.platform
'linux2'
>>>
大家都知道,當今的程式比較流行的是跨平臺。簡單的說就是這段程式既可以在windows下執行,
換到linux下也可以不加修改的執行起來,此時,sys.platform 就派上用場了。
假設,我們想實現一個清除終端程式,linux下用clear, windows下用cls
clean.py檔案:
#!usr/bin/env python
#coding:utf-8
import sys,os
osType=sys.platform
if osType=='linux' or osType=='linux2':
    command='clear'
else:
    command='cls'
os.system(command)
【8】處理標準輸出/輸入:
標準輸出和標準錯誤 (通常縮寫為 stdout 和 stderr) 是內建在每一個 UNIX 系統中的管道。
當你 print 某些東西時,結果前往 stdout 管道;
例如:
>>> for i in range(3):
...     print 'hello python'
... 
hello python
hello python
hello python
>>> import sys
>>> for i in range(3):
...     sys.stdout.write('hello python\n')
... 
hello python
hello python
hello python
【9】當你的程式崩潰並打印出除錯資訊 (例如 Python 中的 traceback (錯誤跟蹤) ) 的時候,資訊前往 stderr 管道。。
>>> l=[1,2]
>>> print l[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
stdout 是一個類檔案物件;呼叫它的 write 函式可以打印出你給定的任何字串。
實際上,這就是 print 函式真正做的事情;它在你列印的字串後面加上一個硬回車,然後呼叫 sys.stdout.write 函式。
在最簡單的例子中,stdout 和 stderr 把它們的輸出傳送到相同的地方。
和 stdout 一樣,stderr 並不為你新增硬回車;如果需要,要自己加上。。。
stdout 和 stderr 都是類檔案物件,但是它們都是隻寫的(它們都沒有 read 方法,只有 write 方法)
由於它們是類檔案物件,因此你可以將其它任何 (類) 檔案物件賦值給它們來重定向其輸出。
【10】重定向輸出:
>>> import sys
>>> print 'hello python'     #標準輸出
hello python
>>> saveout=sys.stdout       #在重定向前儲存stdout,之後你還可以將其設回正常
>>> flog=open('out.log','w') #開啟一個新檔案用於寫入。如果檔案不存在,將會被建立。如果檔案存在,將被覆蓋。
>>> sys.stdout=flog          #所有後續的輸出都會被重定向到剛才開啟的新檔案上。
>>> print  'This message will be logged instead of displayed'
# 這樣只會將輸出結果“列印”到日誌檔案中;螢幕上不會看到輸出。。。
>>> flog.close()             #關閉日誌檔案
>>> sys.stdout=saveout       #將 stdout 設回原來的方式。
>>> print 'ok'               #標準輸出(已經將stdout恢復到原來的方式)
ok
>>> f=open('out.log','r')
>>> f.read() #注意最後的'\n'(說明print會在要列印的字串後面加上一個硬回車)
'This message will be logged instead of displayed\n'
【11】重定向錯誤資訊:
>>> import sys
>>> flog=open('error.log','w')# 開啟要儲存除錯資訊的日誌檔案。
>>> sys.stderr=flog #將新開啟的日誌檔案的檔案物件 賦值給stderr,以重定向標準錯誤。
>>> raise Exception, 'this error will be logged'
# 引發一個異常,沒有在螢幕上打印出任何東西,所有正常的跟蹤資訊已經寫進error.log
#還要注意我們既沒有顯式關閉日誌檔案,也沒有將 stderr 設回最初的值。
#這樣挺好,因為一旦程式崩潰 (由於引發的異常),Python 將替我們清理並關閉檔案 

【12】列印到 stderr:
向標準錯誤寫入錯誤資訊是很常見的,所以有一種較快的語法可以立刻匯出資訊
>>> print 'hello python'   #標準輸出
hello python
>>> import sys
>>> print >> sys.stderr,'hello python' #將單個print語句重定向到stderr,而且不影響後面的print語句
hello python
>>> 
【13】print 語句的快捷語法可以用於寫入任何開啟的檔案 (或者是類檔案物件)。
>>> f=open('print.txt','w')
>>> print >>f,'hello python' #將單個print語句重定向到開啟的檔案物件f
>>> f.close()
>>> f=open('print.txt','r')
>>> f.read()
'hello python\n' # print會在要列印的字串後面加上一個硬回車
>>> f.close()
【14】使用sys模組退出程式:
執行至主程式的末尾時,直譯器會自動退出. 但是如果需要中途退出程式,我們可以呼叫sys.exit 函式,
它帶有一個可選的整數引數返回給呼叫它的程式. 這意味著你可以在主程式中捕獲對sys.exit 的呼叫。
(注:0是正常退出,其他為不正常,可拋異常事件供捕獲!)
>>> import sys
>>> sys.exit(1)
[email protected]:~$ 
#注意 sys.exit 並不是立即退出,而是引發一個 SystemExit 異常。
#這意味著我們可以在主程式中捕獲對 sys.exit 的呼叫
捕獲sys.exit呼叫(1):
exit.py檔案:
#!usr/bin/env python
#coding:utf-8
import sys
print 'hello python'
try:
    sys.exit(1)
except SystemExit: #捕獲到退出異常,,,程式不會退出,後邊的語句會繼續執行。。。
    pass           #捕獲後不做任何操作
print 'ok'
執行結果:
[email protected]:~$ python exit.py
hello python
ok

捕獲sys.exit呼叫(2):
exitfunc.py檔案:
#!usr/bin/env python
#coding:utf-8
import sys
def exitfunc(value):
    '''clear function'''
    print value
    sys.exit(0) #沒有去捕獲 丟擲的SystemExit異常,執行到該語句時退出直譯器
print 'hello!'
try:
    sys.exit(1)  #丟擲的SystemExit異常,被成功捕獲
except SystemExit,value:
    exitfunc(value)
print 'not out!' #該語句不會執行

輸出結果:
[email protected]:~$ python exitfunc.py
hello!
1
[email protected]:~$
以下是python.org庫參考手冊中,摘抄來的,供參考。
Exit from Python. This is implemented by raising the SystemExit exception, 
so cleanup actions specified by finally clauses of try statements are honored, 
and it is possible to intercept the exit attempt at an outer level.
The optional argument arg can be an integer giving the exit status (defaulting to zero),
or another type of object. If it is an integer, zero is considered “successful termination” 
and any nonzero value is considered “abnormal termination” by shells and the like.
Most systems require it to be in the range 0-127, and produce undefined results otherwise. 
Some systems have a convention for assigning specific meanings to specific exit codes,
but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors 
and 1 for all other kind of errors. If another type of object is passed, 
None is equivalent to passing zero, and any other object is printed to sys.stderr 
and results in an exit code of 1. In particular,
sys.exit("some error message") is a quick way to exit a program when an error occurs.
大概意思是說,sys.exit從python程式中退出,將會產生一個systemExit異常,可以為此做些清除除理的工作。
這個可選引數預設正常退出狀態是0,以數值為引數的範圍為:0-127。其他的數值為非正常退出,
還有另一種型別,在這裡展現的是strings物件型別。
如果準備在退出前自己清理一些東西(比如刪除臨時檔案), 
你可以配置一個 "退出處理函式"(exit handler), 它將在程式退出的時候自動被呼叫。。
另一種捕獲sys.exit呼叫的方法:
exit_handler.py檔案:
#!usr/bin/env python
#coding:utf-8
import sys
def exitfunc():
    print 'exit is done!'
sys.exitfunc=exitfunc # 設定退出時要自動呼叫的函式
print 'hello world'
sys.exit(1) # 退出,後邊的語句不再執行( 但在退出之前會自動呼叫exitfunc() )
print 'ok'  #該語句不會執行
執行結果:
[email protected]:~$ python exit_handler.py
hello world
exit is done!


(完)

相關推薦

Python sys模組

本文針對原文做了少量修改和大量的補充。。。 這篇文章主要介紹了Python標準庫之sys模組使用詳解,講解了使用sys模組獲得指令碼的引數、處理模組、 使用sys模組操作 模組搜尋路徑、使用sys模組查詢內建模組、使用sys模組查詢已匯入的模組,重定向輸出以及重定向錯誤等

python 面向物件

本篇將詳細介紹Python 類的成員、成員修飾符、類的特殊成員。 類的成員 類的成員可以分為三大類:欄位、方法和屬性 注:所有成員中,只有普通欄位的內容儲存物件中,即:根據此類建立了多少物件,在記憶體中就有多少個普通欄位。而其他的成員,則都是儲存在類中,即:無論物件

Python---面向對象第三彈

python對象 one iss pri each super left connect ext  Python對象中一些方法 一、__str__ class Teacher: def __init__(self,name,age): self.name

python 面向對象

關心 __iter__ nvi class nic 詳情 mit remove 類名 類的成員 類的成員可以分為三大類:字段、方法和屬性 註:所有成員中,只有普通字段的內容保存對象中,即:根據此類創建了多少對象,在內存中就有多少個普通字段。而其他的成員,則都是保存在類中,

Python開發【第七】:面向物件

上一篇《Python 面向物件(初級篇)》文章介紹了面向物件基本知識: 面向物件是一種程式設計方式,此程式設計方式的實現是基於對 類 和 物件 的使用 類 是一個模板,模板中包裝了多個“函式”供使用(可以講多函式中公用的變數封裝到物件中) 物件,根據模板

零基礎掌握百度地圖興趣點獲取POI爬蟲python語言爬取

好,現在進入進階篇教程。 1.獲取昆明市的bounds值 看到下面這個東西了吧?在文字框裡寫入昆明市,或者其他的行政區劃地名,北京市、朝陽區、大河溝子村什麼的。 這也是通過呼叫百度地圖開放平臺API實現的。 實現起來很簡單,把下面這段程式碼複製到一個

Mysql 入門,增刪改查

bsp com pre sco height name 數據 mysql from 主要已以下兩個表students與students_score,進行數據的增刪改查操作! 1、SELECT 1)select id,tel from students

freenas的CIFS/SMB的使用

img 大小 ifs 退出 freenas 什麽 數據 用戶名 鏡像 這裏是對freenas的進一步使用,關於freenas的介紹與安裝請查看上一篇隨筆:http://www.cnblogs.com/hjc4025/p/7079364.html 我們先來看一下如何使用fre

編碼原則實例------c++程序設計原理與實踐

組類型 運算 奇怪 head 不能 gui 簡單的 版本 布局 編碼原則: 一般原則 預處理原則 命名和布局原則 類原則 函數和表達式原則 硬實時原則 關鍵系統原則 (硬實時原則、關鍵系統原則僅用於硬實時和關鍵系統程序設計) (嚴格原則都用一個大寫字母R及其編號標識,而

有符號數和無符號數------c++程序設計原理與實踐

效果 進階 str 二進制位 bsp () 都是 有符號 重新 有符號數與無符號數的程序設計原則: 當需要表示數值時,使用有符號數(如 int)。 當需要表示位集合時,使用無符號數(如unsigned int)。 有符號數和無符號數混合運算有可能會帶來災難性的後果。例如

動態內存分配存在的問題內存空洞------c++程序設計原理與實踐

我們 程序 動態 height ++ idt 很多 alt 空間 new的問題究竟在哪裏呢?實際上問題出在new和delete的結合使用上。考察下面程序中內存分配和釋放過程: while(1){ Big* p=new big;  //...... Smal

數值限制------c++程序設計原理與實踐

c++程序 its positive size true 設置 malle 設計原理 硬件 每種c++的實現都在<limits>、<climits>、<limits.h>和<float.h>中指明了內置類型的屬性,因此程序

實現求解線性方程矩陣、高斯消去法------c++程序設計原理與實踐

ipy 類型 cat sys sca solution gaussian 拷貝 img 步驟: 其中A是一個n*n的系數方陣 向量x和b分別是未知數和常量向量: 這個系統可能有0個、1個或者無窮多個解,這取決於系數矩陣A和向量b。求解線性系統的方法有很多,這裏使用一種經典

c++11隨機數------c++程序設計原理與實踐

ber linear 而在 希望 double 元素 light eal 區間   隨機數既是一個實用工具,也是一個數學問題,它高度復雜,這與它在現實世界中的重要性是相匹配的。在此我們只討論隨機數哦最基本的內容,這些內容可用於簡單的測試和仿真。在<random>

iOS開發者如何在枯燥的工作中尋求技術的提升

調用 loaded 剛才 高可用 package 如果 sql 讀寫 大牛 技術成長是很多同學面臨的問題,一些工作了幾年的同學會遇到成長瓶頸,覺得自己進步緩慢,無論是公司業務的原因還是個人原因,覺得自己的技術水平得不到成長了。或者一些剛工作沒多久的同學和在找工作的同學,都想

【原創】python學習筆記1-- 自學,爬蟲備註--先佔坑

  Request:使用者將自己的資訊通過瀏覽器(socket client)傳送給伺服器(socket server) Response:伺服器接收請求,分析使用者發來的請求資訊,然後返回資料(返回的資料中可能包含其他連結,如:圖片,js,css等) ps:瀏覽器在接收Res

spring Security4 和 oauth2整合 註解+xml混合使用

Spring Security4 和 oauth2整合使用者密碼授權模式 上篇已經可以正常運行了,不過拿來測試還不夠,下面介紹如何測試oauth2的使用者密碼模式,授權碼模式下一篇說。 不想看這些亂七八糟的,可以直接把程式碼拉下來。 git地址:https://gitee.com/x

HenCoder Android 自定義 View 1-7:屬性動畫 Property Animation

這期是 HenCoder 自定義繪製的第 1-7 期:屬性動畫(進階篇) 簡介 上期的內容,對於大多數簡單的屬性動畫場景已經夠用了。這期的內容主要針對兩個方面: 針對特殊型別的屬性來做屬性動畫; 針對複雜的屬性關係來做屬性動畫。 TypeEvaluator

無業務不伸縮之二,雲監控搭配SLB及ESS

雲端計算ESS彈性伸縮課程 無業務不伸縮之二,雲監控搭配SLB及ESS(進階篇) 連載雲端計算文章主題 後續的連載如下1、 無業務不伸縮之一,雲端計算有ESS2、 無業務不伸縮之二,雲監控搭配SLB及ESS3、無互動不加速,雲端計算有CDN4、無對像不儲存,雲端計算有OSS5、無檔案不儲存,雲端計算有”

淺談月薪3萬 iOS程式設計師 的職業規劃與成長!

前言: 幹了這麼多年的iOS,雖然接觸了許多七七八八的東西、技術,但是感覺本身iOS卻沒有什麼質的飛越,可能跟自己接觸的專案深度有關,於是決定在學習其他技術的同時,加強自己在iOS方面的學習,提高自己的競爭力。 程式設計師薪水有高有低,同樣有五年工作經驗的程式設計師,可能