Python學習 with用法

2021-07-13 11:43:35 字數 3813 閱讀 8120

with語句是什麼?

有一些任務,可能事先需要設定,事後做清理工作。對於這種場景,python的with語句提供了一種非常方便的處理方式。乙個很好的例子是檔案處理,你需要獲取乙個檔案控制代碼,從檔案中讀取資料,然後關閉檔案控制代碼。

如果不用with語句,**如下:

file = open("/tmp/foo.txt")

data = file.read()

file.close()

這裡有兩個問題:

是可能忘記關閉檔案控制代碼;

是檔案讀取資料發生異常,沒有進行任何處理。

下面是處理異常的加強版本:

try:

f = open('***')

except:

print 'fail to open'

exit(-1)

try:

do something

except:

do something

finally:

f.close()

雖然這段**執行良好,但是太冗長了。

這時候就是with一展身手的時候了。除了有更優雅的語法,with還可以很好的處理上下文環境產生的異常。

下面是with版本的**:

with

open("/tmp/foo.txt") as

file:

data = file.read()

with如何工作?

#!/usr/bin/env python

# with_example01.py

class

sample:

def__enter__

(self):

print

"in __enter__()"

return

"foo"

def__exit__

(self, type, value, trace):

print

"in __exit__()"

defget_sample

():return sample()

with get_sample() as sample:

print

"sample:", sample

執行**,輸出如下

bash-3.2$ ./with_example01.py

in __enter__()

sample: foo

in __exit__()

正如你看到的:

enter()方法被執行

enter()方法返回的值 ,這個例子中是」foo」,賦值給變數』sample』 執行**塊,列印變數」sample」的值為 「foo」

exit()方法被呼叫 with真正強大之處是它可以處理異常。

可能你已經注意到sample類的exit方法有三個引數 val, type 和 trace。 這些引數在異常處理中相當有用。我們來改一下**,看看具體如何工作的。

#!/usr/bin/env python

# with_example02.py

class

sample:

def__enter__

(self):

return self

def__exit__

(self, type, value, trace):

print

"type:", type

print

"value:", value

print

"trace:", trace

defdo_something

(self):

bar = 1/0

return bar + 10

with sample() as sample:

sample.do_something()

這個例子中,with後面的get_sample()變成了sample()。這沒有任何關係,只要緊跟with後面的語句所返回的物件有enter() 和exit() 方法即可。此例中,sample()的enter() 方法返回新建立的sample物件,並賦值給變數sample。

**執行後:

bash-3.2$ ./with_example02.py

type: 'exceptions.zerodivisionerror'>

value: integer division or modulo by

zero

trace: at

0x1004a8128>

traceback (most recent call last):

file "./with_example02.py", line

19, in

sample.do_something()

file "./with_example02.py", line

15, in do_something

bar = 1/0

zerodivisionerror: integer division or modulo by

zero

實際上,在with後面的**塊丟擲任何異常時,exit() 方法被執行。正如例子所示,異常丟擲時,與之關聯的type,value和stack trace傳給exit() 方法,因此丟擲的zerodivisionerror異常被列印出來了。開發庫時,清理資源,關閉檔案等等操作,都可以放在exit方法當中。

另外,exit除了用於tear things down,還可以進行異常的監控和處理,注意後幾個引數。要跳過乙個異常,只需要返回該函式true即可。

下面的樣例**跳過了所有的typeerror,而讓其他異常正常丟擲。

def

__exit__

(self, type, value, traceback):

return isinstance(value, typeerror)

上文說了exit函式可以進行部分異常的處理,如果我們不在這個函式中處理異常,他會正常丟擲,這時候我們可以這樣寫(python 2.7及以上版本,之前的版本參考使用contextlib.nested這個庫函式):

try:

with

open( "a.txt" ) as f :

do something

except ***error:

do something about exception

總之,with-as表示式極大的簡化了每次寫finally的工作,這對保持**的優雅性是有極大幫助的。

如果有多個項,我們可以這麼寫:

with

open("x.txt") as f1, open('***.txt') as f2:

do something with f1,f2

因此,python的with語句是提供乙個有效的機制,讓**更簡練,同時在異常產生時,清理工作更簡單。

Python學習 python陣列模組用法

array模組是python中實現的一種高效的陣列儲存型別。它和list相似,但是所有的陣列成員必須是同一種型別,因此在建立陣列的時候,就確定了陣列的型別 計算機為陣列分配一段連續的記憶體,從而支援對陣列隨機訪問 由於項的位址在編號上是連續的,陣列某一項的位址可以通過將兩個值相加得出,即將陣列的基本...

python 學習 筆記 format 用法

習慣了用 print s 這種結構來格式化輸出,今天無意中看到python 有format函式,讀了一遍它的幫助文件。使用起來還是比較方便的。摘錄出來。基本的按順序輸出 python版本需要2.7以上 format a b c a b c 輸出順序可以調整 format a b c b a c 右對...

python學習 while True的用法

在學習過程中,經常能遇到採用while true的用法。下面以乙個例子進行說明 建立乙個使用者登入系統,使用者輸入使用者名稱和密碼,如果正確就可以進入系統。1 我自己最開始的寫法 d 資料庫字典,所有使用者的使用者名稱密碼儲存在此 name input 請輸入您的使用者名稱 if name in d...