好記性不如爛筆頭,看到Python Optional Variables這一塊,把學習的東西記錄下來
一. 可選的環境變量設置
會寫Java Hello World的同學一定知道如何設置環境變量,比如:JAVA_HOME,CLASSPATH等。
Python中也一樣有類似的環境變量,有一些還是可選的(比如:PYTHONPATH, PYTHONSTARTUP等)
設置PYTHONPATH
這個環境變量有什麼用呢?
我們知道在導入模塊時(比如:import some_module_name),Python需要在某些路徑(即sys.path這個列表中的路徑)中去尋找相應的模塊,而PYTHONPATH這個變量就是告訴Python,將它的值也加入到搜索路徑中(即將PYTHONPATH的值合併到sys.path列表中)。
export PYTHONPATH=/tmp python -c "import sys; print 'found' if '/tmp' in sys.path else '' "
輸出結果是:found
說明/tmp在sys.path中被找到了(即/tmp附加到了sys.path中)
2. 設置PYTHONSTARTUP
如果這個環境變量的值是一個可讀的文件,那麼該文件中的Python命令會在交互模式啓動之前執行。
echo "print 'hello world'" > /tmp/a.py export PYTHONSTARTUP=/tmp/a.py python
在啓動python交互模式後,會看到有hello world已經被輸出了。
3. 設置PYTHONHOME
一般在這個變量沒有被設置的情況下,Python中的sys.path會列出一些模塊的搜索路徑。
# 比如: ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/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']
Python模塊的搜索路徑一般默認是sys.prefix/lib,可以看到很多路徑是 /usr/lib/... 這種,其中/usr 就是sys.prefix這個變量的值(windows上可能是你安裝Python的目錄,比如: C:\Python2.7)。
如果人工指定了PYTHONHOME,那麼sys.prefix的值就會被替換。
隨便替換PYTHONHOME的值,可能造成Python無法啓動,替換前請備份sys.prefix的值
4. 設置PYTHONCASEOK
這個變量只對Windows起效,可以設置爲任意的值(比如:SET PYTHONCASEOK=OK)
設置了以後,Python對模塊的導入,將忽略大小寫(只對用戶module忽略大小寫,對built-in module還是大小寫敏感)
5. 設置PYTHONIOENCODING
看這個名字,IO Encoding可以猜到這個東西是和輸入輸出有關的。對,這個環境變量的作用就是指定Python程序標準輸入輸出(stdin,stdout,stderr)的編碼。
關於這個東西的運用,請參考:http://www.soimort.org/posts/118/ 太長不看 :D
再補充一些關於encode和decode的要點:
在Python 2.x中,str類型的字符串,都是指string of bytes(二進制流的表示形式),一般來說
1). '...'.decode([encoding_name])是將string of bytes轉化成unicode string
運用場景是,從網絡或者文件中讀取了二進制流,然後將其轉化爲unicode字符串,便於閱讀。
2). u'....'.encode([encoding_name])是將unicode string轉化成string of bytes
運用場景是,將unicode字符串轉化成二進制流(Java的叫法也稱爲字節流),然後推向網絡或者文件中。
另外,還有兩個方法,str.encode和unicode.decode,這兩個方法意義不大(幾乎很少運用)
"...".encode() 會先默認隱式的用default encoding去decode,即調用"...".decode(sys.getdefaultencoding()) ,然後再繼續調用"...".encode()
而u"...".decode()也會先默認隱式的調用u"...".encode(sys.getdefaultencoding()),然後繼續調用u"...".decode()
二. 使用pdb模塊調試、跟蹤腳本
有些時候,需要在沒有IDE幫助的情況下,對腳本的運行情況進行調試、跟蹤,可以使用Python內置的pdb模塊(參考:https://docs.python.org/2/library/pdb.html)
一個簡單的例子:
對腳本test.py進行跟蹤調試
#! /usr/bin/env python def foo(): s = 0 for i in range(3): s += i print s if __name__ == "__main__": foo()
運行命令:
python -m pdb test.py
顯示類似如下所示:
> /tmp/test.py(3)<module>() -> def foo(): (Pdb) l 1 #! /usr/bin/env python 2 3 -> def foo(): 4 s = 0 5 for i in range(3): 6 s += i 7 print s 8 9 10 if __name__ == "__main__": 11 foo() (Pdb) n > /tmp/test.py(10)<module>() -> if __name__ == "__main__": (Pdb)
(pdb)是調試提示符,在提示符下可以輸入命令(具體參考文檔)
可以在(pdb)提示符下,查看標量的值,可以使用print 語句打印
常用的簡單命令有:
命令全稱 | 簡寫 | 命令描述 | |
list | l | 列出當前執行腳本的內容(其中有箭頭標註當前執行到的位置) | |
next | n | 執行下一步,遇到函數不進入其內部。(相當於IDE中的step over) | |
step | s | 執行下一步,遇到函數進入其內部。(相當於IDE中的step into) | |
break | b | 設置斷點,如果不帶參數,則列出當前執行腳本中的所有斷點(號)。 也可以帶參數,比如,執行: b 6)代表在腳本的第6行設置斷點,如右邊所示,它的斷點號是1。 | (Pdb) b 6 Breakpoint 1 at /tmp/test.py:6 (Pdb) l 5 for i in range(3): 6 B s += i 7 print s 8 9 10 -> if __name__ == "__main__": 11 foo() |
clear | cl | 清除腳本中的斷點。 1)不帶參數,會詢問是否清除腳本中的所有斷點 2)帶參數會清除指定的斷點。(注意清除的格式) |
所以,要清除上面設置的第6行的斷點,要麼使用 cl 1 (清除斷點號是1的斷點);要麼使用 cl test.py:6 (清除test.py中的第6行) 使用 cl 6是錯誤的,因爲目前爲止,沒有標號是6的斷點!! |
continue | c | 繼續執行腳本,直到遇到斷點停止。 | |
quit | q | 退出調試 |