contextlib-@contextmanager与closi

2020-04-07  本文已影响0人  huashen_9126

ftp操作完成后自动关闭连接:

import ftplib
from contextlib import contextmanager

class FTP(object):
    def __init__(self, host, port, user, passwd):
        self.ftp = ftplib.FTP()
        self.ftp.connect(host, port)
        self.ftp.login(user, passwd)
        print(self.ftp.welcome)

    def download_file(self, local_file, remote_file):
        file_handler = open(local_file, 'wb')
        self.ftp.retrbinary("RETR %s" % remote_file, file_handler.write)
        file_handler.close()
        return True

    def close(self):
        self.ftp.close()

@contextmanager
def ftp_download(host, port, user, passwd):
    print('Begin')
    f = FTP(host, port, user, passwd)
    yield f
    f.close()
    print('End')

#使用
with ftp_download('172.16.19.70', 21, 'ftpuser', '1qaz@WSX') as f:
    f.download_file('xxxxx', 'yyyyy')

简单应用场景:在某段代码执行前后自动执行特定代码

from contextlib import contextmanager

@contextmanager
def tag(name):
    print(f"<{name}>")
    yield
    print(f"</{name}>")

with tag("h1"):
    print("hello")
    print("world")

#结果:
<h1>
hello
world
</h1>

ftp自动关闭连接的closing实现:

import ftplib
from contextlib import closing

class FTP(object):
    def __init__(self, host, port, user, passwd):
        self.ftp = ftplib.FTP()
        self.ftp.connect(host, port)
        self.ftp.login(user, passwd)
        print(self.ftp.welcome)

    def download_file(self, local_file, remote_file):
        file_handler = open(local_file, 'wb')
        self.ftp.retrbinary("RETR %s" % remote_file, file_handler.write)
        file_handler.close()
        return True

    def close(self):
        self.ftp.close()
        print('End')

with closing(FTP('172.16.19.70', 21, 'ftpuser', '1qaz@WSX')) as f:
    f.download_file(r'C:\Users\geek\Desktop\xx', '/xx.PH')

closing也是一个经过@contextmanager装饰的generator,相当于:

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()
上一篇下一篇

猜你喜欢

热点阅读