(四)指令碼上下文

2021-06-22 03:16:41 字數 4000 閱讀 1264

上下文,是指python指令碼執行時所處的環境。

對於python指令碼而言,當前工作目錄是乙個十分重要的概念:指令碼在讀寫檔案時,如果沒有指明絕對路徑,則預設檔案所處的路徑為當前工作目錄。我們可以呼叫os.getcwd方法顯式地獲取cwd,也可以通過os.chdir修改它。

所以,檔名在沒有指明絕對路徑的情況下會對映到cwd下,和環境變數pythonpath沒有任何關係。指令碼是在cwd下執行的,而不是指令碼所處的檔案目錄。相反,import語句總是先搜尋指令碼所處的檔案目錄,不是cwd(除非指令碼剛好處在cwd下)。為了清晰這個概念,下面進行一步說明。

cwd,檔案和匯入路徑

在命令列解析器(如windows中的ms-dos)中執行python指令碼時,cwd指命令列游標所處的當前路徑。如圖:

cwd的值為"c:\\users\\huwz",不是"d:".

另外,python會自動將cwd和指令碼所處的檔案目錄插入到sys.path的0和1號索引位置。cwd和指令碼所處的目錄一般是不同的,如果想要這兩個值相同,可以雙擊指令碼檔案,直接執行指令碼(最好在指令碼結束的位置新增互動的語句用於暫停,否則執行結束後,dos視窗會迅速消失)。

前面提到乙個pythonpath的概念,用於指明指令碼所處的目錄。可以在系統環境變數中新增pythonpath,進行手動設定。一旦設定之後,處在pythonpath路徑下的python指令碼可以在任意位置執行。

有一點需要註明:如果指令碼處於使用者自定義的包目錄下(比如:d:/pp4e/python_scripts)不在pythonpath中,那麼其他指令碼檔案想要import該目錄下的模組(.py檔案),需要在import語句中新增完整包目錄(import pp4e.python_scripts.*)。如果頂級包(pp4e)所處的目錄不在sys.path中,必須新增到到pythonpath中,否則就會丟擲importerror異常。

如何獲取命令列中的引數,就好像函式呼叫傳遞引數一樣呢?模組屬性sys.argv可以完成這個工作。sys.argv是乙個列表,用於收集命令列執行指令碼時傳遞的引數。例如:

指令碼test.py中sys.argv的值為:['test.py','hello,world']。由這個例子可知:sys.argv從目標模組名開始收集,以空白符為分隔符,順序將所有的命令列引數收集起來,組織成列表。當然,你可以將引數分為位置引數和選項引數。所謂位置引數,就是按照命令列出現的順序依次排列的引數,引數值和次序嚴格對應;選項引數是"-name value"對,比如:-h helpinfo。這裡helpinfo和-h相關聯。在處理選項引數時,可以先獲取選項名,再根據選項名,來得到對應的選項引數的值。

當然還可以參考以下模組工具來解析命令列引數

分為標準輸入流,標準輸出流和標準錯誤資訊流,和c++中的標準輸入輸出流相似。對應的python物件分別為sys.stdin,sys.stdout和sys.stderr。常規用法如下:

sys.stdout.write('hello\n')	# print('hello')

str = sys.stdin.readline() # str = raw_input(),3.x支援sys.stdin.read()

sys.stderr.write('error\n') # 在idle中高亮顯示錯誤資訊"error"

這三個物件實際上是python自動建立的檔案物件,屬於可遞迴的物件,支援

for...in...的語法

一般而言,標準輸出流將文字列印在程式啟動的控制台視窗中(比如idle,ms-dos),標準輸入流從鍵盤獲取文字資訊,標準錯誤資訊流將python錯誤資訊列印到控制台視窗中。

有必要解釋下流的概念。流其實是指資料傳輸。計算機中,資料的傳輸在硬體層面上是以位元組進行的,如果不關心資料的具體內容,資料的傳輸就是位元組的傳輸,就像流動的水一樣,所以稱為流。流的行為需要媒介支援,純粹的硬體媒介就是資料線。當然這裡討論「硬媒介」是沒有意義的,我們關注的是與硬體媒介相對應的「軟媒介」。在windows中存在這樣的「軟媒介」,也是我們所熟知的系統緩衝區。

依據個人的理解,windows作業系統在與外部裝置交換資料時,由於資料處理速度以及串並行的差別,需要進行資料緩衝,這樣可以保證資料不會丟失。預設情況下,緩衝區的入口和出口連線的分別是系統和外設(如鍵盤和顯示器)。比如python中的標準輸入流和input(),緩衝區入口為鍵盤裝置,出口為系統呼叫;標準輸出流和print(),緩衝區的入口為系統呼叫,出口是列印終端(就是前文提到的控制台視窗)。系統緩衝區屬於公共資源,因而可以用於不同程序間的資訊交換。

python的預設緩衝區就是系統緩衝區,只是它既可以從系統寫入資料(輸出流),也可以讀出資料到系統(輸入流),所以扮演不同的角色,也就有輸入緩衝區和輸出緩衝區的分別。

能不能改變這種模式呢?windows作業系統存在流重定向指令("")和管道指令,其實質就是將緩衝區的入口或者出口進行重定向。

(以上關於流的解釋純屬個人見解,有興趣的同學可以去參考相關資料)

通過重定向指令""來實現流的重定向

將資料檔案data.txt中的資料作為tes.py指令碼的輸入。

tes.py:

import sys

datalist =

while true:

try:

data = raw_input()

except eoferror:

datalist.sort()

print datalist

break

else:

執行結果如下:

通過管道指令實現重定向

資料**變為datafrom.py指令碼,通過"|"指令,將該指令碼的列印內容賦值給tes.py

datafrom.py:

print "1\n2\n8\n9\n0\n11"
執行結果:

管道指令是可以串聯的,而且不限定於py指令碼,只要可以在shell視窗中執行的程式都可以。所謂的串聯,舉個例子說明就清楚了。如果有a.py,b.py和c.py指令碼,可以有如下的命令列:python a.py | b.py | c.py,表示a.py的列印結果給b.py,然後再將列印結果給c.py。

python的指令碼通過管道可以實現通訊。比如上例中a.py的資料存入sys.stdout,b.py可以通過sys.stdin.readline()(讀取的內容包括'\n')讀取a.py列印的文字。也就是說只要a.py中有列印結果,b.py就可以獲取。

重定向指令的弊端和解決辦法

前面介紹了重定向的方法:將檔案作為緩衝區的入口或者出口,進行流的重定向。這個方法的弊端也很明顯,如果將乙個很大的檔案讀入記憶體,因為是一次性讀入,等待時間會很長。改進的辦法是分塊讀入,分塊處理。管道指令可以解決這個問題。將資料放入.py指令碼中,通過for迴圈進行資料分解,得到的資料塊存入sys.stdout,這樣只要緩衝區中有資料,管道另一端的指令碼就可以通過syss.stdin.readline()獲取。

例如a.py迴圈列印字串陣列;b.py接受乙個輸入的字串然後列印。可以在a.py和b.py之間建立管道。**如下:

a.py:

import sys

strings = ['name: python\n', 'country: china\n', 'version: 2.7.2\n']

for i in strings:

sys.stdout.write(i)

b.py:

import sys

while true:

strs = sys.stdin.readline()

if not strs:

break;

sys.stdout.write("b=> " + strs)

執行結果:

flask基礎四 請求上下文

內容回顧 flask回顧 1.dbutils 資料庫連線池 然後執行mysql資料庫,在mysql新建立乙個資料庫,並建立乙個新的表,錄入資料。import pymysql from dbutils.pooleddb import pooleddb pool pooleddb creator pym...