栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

装饰委派File对象以添加功能

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

装饰委派File对象以添加功能

1和2是合理的解决方案,但仅重写write()是不够的。

问题是Popen需要将文件句柄附加到进程,因此Python文件对象不起作用,它们必须是OS级别的。要解决这个问题,您必须拥有一个具有os级文件句柄的Python对象。我能想到的解决此问题的唯一方法是使用管道,因此您要写入一个os级文件句柄。但是,然后您需要另一个线程来坐下来并轮询该管道以供读取内容,以便可以对其进行记录。(因此,严格来说,这是2的实现,因为它委派了日志记录)。

说完了:

import ioimport loggingimport osimport selectimport subprocessimport timeimport threadingLOG_FILENAME = 'output.log'logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)class StreamLogger(io.IObase):    def __init__(self, level):        self.level = level        self.pipe = os.pipe()        self.thread = threading.Thread(target=self._flusher)        self.thread.start()    def _flusher(self):        self._run = True        buf = b''        while self._run: for fh in select.select([self.pipe[0]], [], [], 0)[0]:     buf += os.read(fh, 1024)     while b'n' in buf:         data, buf = buf.split(b'n', 1)         self.write(data.depre()) time.sleep(1)        self._run = None    def write(self, data):        return logging.log(self.level, data)    def fileno(self):        return self.pipe[1]    def close(self):        if self._run: self._run = False while self._run is not None:     time.sleep(1) os.close(self.pipe[0]) os.close(self.pipe[1])

这样,该类将启动os级管道,Popen可以将stdin / out /
error附加到该子进程。它还启动一个线程,该线程每秒轮询该管道的另一端以进行记录,然后将其记录到日志记录模块中。

此类可能为了实现完整性而应实现更多功能,但无论如何在这种情况下仍然有效。

示例代码:

with StreamLogger(logging.INFO) as out:    with StreamLogger(logging.ERROR) as err:        subprocess.Popen("ls", stdout=out, stderr=err, shell=True)

output.log最终如下所示:

INFO:root:output.logINFO:root:streamlogger.pyINFO:root:andINFO:root:soINFO:root:on

经过Python 2.6、2.7和3.1测试。

我认为1和3的任何实现都需要使用类似的技术。它有点涉及,但是除非您可以正确地使Popen命令本身记录日志,否则我没有更好的主意)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/641172.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号