1. 程式人生 > 實用技巧 >物件支援上下文管理之with下的__enter__方法,和__exit__方法

物件支援上下文管理之with下的__enter__方法,和__exit__方法

最先版本的

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):
        self.tn = Telnet(self.addr, self.port)
        self.history = deque()

        # user
        t= self.tn.read_until('Login: ')
        stdout.write(t)
        user = stdin.readline()
        self.tn.write(user)

        # password
        t= self.tn.read_until('password')
        if t.startswith(user[:-1]): t = t[len(user)+1:]
        stdout.write(t)
        self.tn.write(stdin.readline())

        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):
        self.tn.close()
        self.tn = None
        with open(self.addr + '_history.txt','w')as f:
            f.writelines(self.history)

client = TelnetClient('127.0.0.1')

print('\n start....')
client.start()  # 啟動clinet方法
print('\n cleanup')
client.cleanup()    # 退出,清理記憶體

更新版本的

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):
        # self.tn = Telnet(self.addr, self.port)
        # self.history = deque()
        
        # user
        t= self.tn.read_until('Login: ')
        stdout.write(t)
        user = stdin.readline()
        self.tn.write(user)

        # password
        t= self.tn.read_until('password')
        if t.startswith(user[:-1]): t = t[len(user)+1:]
        stdout.write(t)
        self.tn.write(stdin.readline())

        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):
        # self.tn.close()
        # self.tn = None
        # with open(self.addr + '_history.txt','w')as f:
        #     f.writelines(self.history)
        pass

    def __enter__(self):
        self.tn = Telnet(self.addr, self.port)
        self.history = deque()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.tn.close()
        self.tn = None
        with open(self.addr + '_history.txt', 'w')as f:
            f.writelines(self.history)

'''
client = TelnetClient('127.0.0.1')
print('\n start....')
client.start()
print('\n cleanup')
client.cleanup()
'''
with TelnetClient('127.0.0.1') as client:
    client.start()

with 監控 enter 和 __exit__方法:

#_*_ encoding: utf-8 _*_   @author: ty  hery   2019/12/20


開啟檔案物件
f = open('03.txt','wb')
# 2,向檔案寫入內容
try:
    f.write(b'hello flask')
except Exception:
    pass
finally:
    # 3,關閉檔案
    f.close()

f = open('01.txt','wb') # 等同於下面的with open
# with是上下文管理器,內部的程式碼全部都在with的監管之下執行的
with open('03.txt','wb') as f:   # 在f物件中含有__enter__,和__exit__方法,with呼叫這些方法
    f.write(b'hello flask 01')
    f.write(b'hello flask 02')
    f.write(b'hello flask 03')
    f.write(b'hello flask 04')
    f.write(b'hello flask 05')

class Foo(object):
    def __enter__(self):
        '''進入with語句的時候被with呼叫'''
        print('enter called')

    def __exit__(self,exc_type,exc_val,exc_tb):
        '''離開with語句的時候被with呼叫'''
        print('exit called')
        print('exc_type: %s' %exc_type)
        print('exc_val: %s' %exc_val)
        print('exc_tb: %s' %exc_tb)
with Foo() as  foo:
    print('hello python ')
    a =1/0
    print('hello end')