Python中with用法詳解


一 、with語句的原理

  • 上下文管理協議(Context Management Protocol):包含方法 __enter__()__exit__(),支持該協議的對象要實現這兩個方法。
  • 上下文管理器(Context Manager):支持上下文管理協議的對象,這種對象實現了__enter__()__exit__()方法。上下文管理器定義執行with語句時要建立的運行時上下文,負責執行with語句塊上下文中的進入與退出操作。通常使用with語句調用上下文管理器,也可以通過直接調用其方法來使用。

說完上面兩個概念,我們再從with語句的常用表達式入手,一段基本的with表達式,其結構是這樣的:

1 with EXPR as VAR:
2 
3     BLOCK

其中EXPR可以是任意表達式;as VAR是可選的。其一般的執行過程是這樣的:

  1. 執行EXPR,生成上下文管理器context_manager;
  2. 獲取上下文管理器的__exit()__方法,並保存起來用於之后的調用;
  3. 調用上下文管理器的__enter__()方法;如果使用了as子句,則將__enter__()方法的返回值賦值給as子句中的VAR;
  4. 執行BLOCK中的表達式;
  5. 不管是否執行過程中是否發生了異常,執行上下文管理器的__exit__()方法,__exit__()方法負責執行“清理”工作,如釋放資源等。如果執行過程中沒有出現異常,或者語句體中執行了語句break/continue/return,則以None作為參數調用__exit__(None, None, None);如果執行過程中出現異常,則使用sys.exc_info得到的異常信息為參數調用__exit__(exc_type, exc_value, exc_traceback)
  6. 出現異常時,如果__exit__(type, value, traceback)返回False,則會重新拋出異常,讓with之外的語句邏輯來處理異常,這也是通用做法;如果返回True,則忽略異常,不再對異常進行處理。

二、自定義上下文管理器

  Pythonwith語句是提供一個有效的機制,讓代碼更簡練,同時在異常產生時,清理工作更簡單。

# coding = utf-8
# 2019/7/19  Luckyxxt:有趣的事,Python永遠不會缺席!
#!/usr/bin/env python

class DBManager(object):
    def __init__(self):
        pass

    def __enter__(self):
        print('__enter__')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__')
        return True

def getInstance():
        return DBManager()

with getInstance() as dbManagerIns:
    print('with demo')

 

  with后面必須跟一個上下文管理器,如果使用了as,則是把上下文管理器的 __enter__() 方法的返回值賦值給 target,target 可以是單個變量,或者由“()”括起來的元組(不能是僅僅由“,”分隔的變量列表,必須加“()”)

代碼運行結果如下:

復制代碼
1 '''
2 __enter__
3 with demo
4 __exit__
5 
6 '''
復制代碼

結果分析:當我們使用with的時候,__enter__方法被調用,並且將返回值賦值給as后面的變量,並且在退出with的時候自動執行__exit__方法

復制代碼
 1 class With_work(object):
 2     def __enter__(self):
 3         """進入with語句的時候被調用"""
 4         print('enter called')
 5         return "xxt"
 6 
 7     def __exit__(self, exc_type, exc_val, exc_tb):
 8         """離開with的時候被with調用"""
 9         print('exit called')
10 
11 
12 with With_work() as f:
13     print(f)
14     print('hello with')
復制代碼
復制代碼
1 '''
2 enter called
3 xxt
4 hello with
5 exit called
6 
7 '''
復制代碼

三、總結

  自定義上下文管理器來對軟件系統中的資源進行管理,比如數據庫連接、共享資源的訪問控制等。

     

 

轉自:https://www.cnblogs.com/xxtalhr/p/11211347.html#_labelTop 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM