程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python實現上下文管理詳解

編輯:Python

1、如何讓對象支持上下文管理?

        實際案例:

                我們實現了一個telnet客戶端TelnetClient,調用實例的start()方法啟動客戶端與服務器交互,交互完畢後需調用cleanup()方法,關閉已連接的socket,以及將操作歷史記錄寫入文件並關閉。

                能否讓TelnetClient的實例支持上下文管理協議,從而替代手工調用cleanup()方法。

        解決方案:

                實現上下文管理協議,需定義實例的__enter__,__exit__方法,它們分別在with開始和結束時被調用。

2、代碼演示

(1)上下文管理的例子

'''
經常在對文件操作的時候使用上下文管理使用with語句,
使用上下文管理的好處就是在with語句結束以後不用顯示的close去關閉文件,
這樣一個清理工作會交給上下文管理協議,讓它們自動幫我們完成。
'''
with open('demo.txt', 'w') as f:
f.write('abcdef')
f.writelines(['xyz\n', '123\n'])
# f.close()

(2)實現一個類的對象支持上下文管理協議

from telnetlib import Telnet
from sys import stdin, stdout
from collections import deque
class TelnetClient(object):
def __init__(self, addr, port=23):
self.addr = addr
self.port = port
self.tn = None
def start(self):
# 人為顯示拋出一個異常,用來證明即使有異常__exit__同樣會被調用
# raise Exception('Test')
# 進行登錄操作輸入用戶名和密碼
# user
t = self.tn.read_until(b'login: ')
stdout.write(t)
user = stdin.readline()
self.tn.write(user)
# password
t = self.tn.read_until(b'password: ')
if t.startswith(user[:-1]):
t = t[len(user) + 1:]
stdout.write(t)
self.tn.write(stdin.readline())
# 登錄到服務器的shell當中
t = self.tn.read_until('$ ')
stdout.write(t)
while True:
uinput = stdin.readline()
if not uinput:
break
self.history.append(uinput)
self.tn.write(uinput)
t = self.tn.read_until('$ ')
stdout.write(t[len(uinput) + 1:])
def cleanup(self):
pass
def __enter__(self):
# Telnet連接對象
self.tn = Telnet(self.addr, self.port)
# 創建隊列存儲用戶的操作歷史記錄
self.history = deque()
# __enter__()返回的才是with中as的對象,self自身
return self
# 3個參數分別為異常類型、異常值、跟蹤棧信息
# 無異常的情況下三個參數都是None
def __exit__(self, exc_type, exc_val, exc_tb):
# print('In __exit__')
# 關閉服務器連接的socket
self.tn.close()
self.tn = None
with open(self.addr + 'history.txt', 'w') as f:
f.writelines(self.history)
# 默認返回None
# return True # 不拋出異常
with TelnetClient('127.0.0.1') as client:
client.start()
print('END')


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved