Python中的上下文管理器和else塊

2021-09-14 02:35:49 字數 2854 閱讀 9524

1、掌握if語句之外的else的用法;

2、掌握上下文管理器的定義、協議、使用和with塊;

3、掌握有用的@contextmanger裝飾器。

1、else塊介紹

if/else中if和else是同級對立的語句,對立是指流程經過一層if/else語句只能對應一種處理語句。而else在for/else,while/else,try/else語句中的功能則截然不同。後者中的else功能如下:

下面以for/else為例進行**實現:

if i.isupper():

break

else:

raise valueerror('no upper string was found')

2、try/else塊背後的程式設計風格

try/except不僅用於處理錯誤,還用於處理錯誤,這屬於eafp程式設計風格。

1、上下文管理器介紹

上下文管理器(context manger):在操作檔案和建立資料庫連線的時候,我們最終需要關閉資源,這就是上下文管理器存在的意義。

上下文管理器協議:包含__enter__和__exit__兩個方法。

語法:try/finally模式和with語句

例項:try/finally模式

try:

f = open('test.txt', 'a+')

f.write('foo\n')

finally:

f.close()

接下來我們用with語句進行替換:

例項:with語句

with open('test.txt', 'a+') as f:

f.write('foo\n')

分析:open 的返回值賦值給變數 f,當離開 with **塊的時候,系統會自動呼叫 f.close() 方法。

總結:with塊的功能在於簡化try/finally模式。with語句在開始執行時會在上下文管理器物件上呼叫__enter__,而with語句結束時會呼叫__exit__方法。

tips:with語句中的as語句是可選的,as語句將__enter__返回的值繫結到as語句後的變數。值得注意的是,對於open函式必須加上as字句來獲取檔案的引用。

2、自定義上下文管理器

在掌握基本上下文管理器和with語句後,我們通過自定義上下文管理器來深刻認識with語句和__enter__以及__exit__的聯絡。

例項:自定義滿足上下文管理器協議的類

class openfiledemo(object):

def __init__(self, filename):

self.filename = filename

self.f = open(self.filename, 'a+')

return self.f

def __exit__(self, exc_type, exc_value, traceback):

self.f.close()

if exc_type != syntaxerror:

return true

return false

with openfiledemo('test.txt') as f:

f.write('foo\n')

3、異常處理

當上下文管理器遇到異常時由__exit__方法處理。傳給__exit__方法的三個引數如下:

exc_type:異常類(例如syntaxerror)。

exc_value:異常例項。有時會有引數傳給異常構造方法,例如錯誤資訊,可以使用exc_value.args獲取這些引數。

traceback:traceback物件。

@contextmanger裝飾器是contextlib模組中的工具,它可以將包含yield的語句變成上下文管理器。

其中,yield之前的語句在__enter__方法中執行yield之後的語句在__exit__方法執行,yield後面的值是函式的返回值,繫結到實際呼叫的with中的as子句的目標變數上

如此可以避免編寫乙個類來實現上下文管理器協議。

例項:@contextmanger裝飾器應用之計時器

import contextlib

import time

@contextlib.contextmanager

def timer():

start=time.time()

yield

end=time.time()

usedtime=end-start

print('running time was %r seconds'%usedtime)

with timer() as usedtime:

time.sleep(1)

注意:一旦with塊在呼叫timer出現異常時,丟擲的異常會在timer函式中的yield表示式中再次丟擲。如果timer函式沒有處理異常的**就會導致函式執行中止,系統處於無效狀態。因此必要時在上下文管理器函式中使用try/finally語句防範錯誤。

@contextmanger集合了三個不同的python特性:函式裝飾器、生成器和with語句,非常實用!

最後說明contextlib模組中包含的實用工具:

顯然,在這些實用工具中,使用最廣泛的是 @contextmanager 裝飾器,因此要格外留心。這個裝飾器也有迷惑人的一面,因為它與迭代無關,卻要使用 yield 語句。

with和python上下文管理器

下面是3種開啟資源的方式,一種直接開啟,一種try方式,一種with方式,每個的方式的優缺點就不說了,這裡記錄下with先骨幹的內容。f open a.txt r do thing f.close try f open a.txt r do thing except ioerror as e pri...

python 上下文管理器

上下文管理器允許你在有需要的時候,精確地分配和釋放資源。使用上下文管理器最廣泛的案例就是with語句了。想象下你有兩個需要結對執行的相關操作,然後還要在它們中間放置一段 上下文管理器就是專門讓你做這種事情的。舉個例子 with open some file w as opened file open...

python上下文管理器

上下文管理器是乙個包裝任意 塊的物件。上下文管理器保證進入上下文管理器時,每次 執行的一致性 當退出上下文管理器時,相關資源會被正確 這裡被正確 指的是在 exit 方法自定義 比如關閉資料庫游標 值得注意的是,上下文管理器一定能夠保證退出步驟的執行。如果進入上下文管理器,根據定義,一定會有退出步驟...