【Python】Python日志无延迟实时写入

我在用python生成日志时,发现无论怎么flush(),文件内容总是不能实时写入,导致程序意外中断时一无所获。

有没有办法将结果打印到屏幕的同时,也实时打印到日志呢?看下文。

(1)原理

open函数的buffering函数可以实现无缓冲写入。

open(file, ‘w’, buffering = a)          # buffering设置缓冲行为

全缓冲: a 是正整数,当缓冲区文件大小达到a大小时候,写入磁盘

行缓冲: buffering = 1, 缓冲区碰到 \n 换行符的时候就写入磁盘

无缓冲:buffering = 0 ,写多少,存多少

如果要使用无缓冲模式,需要用二进制模式打开文件,并且把要写入的信息转换二进制字符串格式。

如果没用二进制打开文件会提示ValueEorror;

如果没把字符串转成二进制会提示:TypeError: a bytes-like object is required, not ‘str’。

Python将字符串转换为字节的三种方法:

string = '北京'

a = string.encode('utf-8')    # 编码
b = bytes(string,'utf-8')     # 强制类型转换
c = b'\n'                     # 加前缀(仅限于英文字母前)

(2)写一个高效的日志类

下面的类效率更高、报错更少:

class Logger(object):
    def __init__(self, log_path="default.log"):
        import sys
        self.terminal = sys.stdout
        self.log = open(log_path, "w", buffering=64)

    def print(self, *message):
        message = ",".join([str(it) for it in message])
        self.terminal.write(str(message) + "\n")
        self.log.write(str(message) + "\n")

    def flush(self):
        self.terminal.flush()
        self.log.flush()

    def close(self):
        self.log.close()

注意:buffering=64意思就是等到64个字母的时候写入文件,一个字母是1字节。这个参数可以调大调小。

然后在正文里调用类:

log = Logger("data.log")
log.print('start!')

这样log.print()既能在屏幕打印,也能无延迟写入日志了!

(3)写一个变态的日志类

以二进制的方式写入,能实现0缓冲

class Logger(object):
    def __init__(self, log_path="default.log"):
        import sys
        self.terminal = sys.stdout
        self.log = open(log_path, "wb", buffering=0)

    def print(self, *message):
        message = ",".join([str(it) for it in message])
        self.terminal.write(str(message) + "\n")
        self.log.write(str(message).encode('utf-8') + b"\n")

    def flush(self):
        self.terminal.flush()
        self.log.flush()

    def close(self):
        self.log.close()

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值