最近在写TensorFlow的教程,TensorFlow的输出有点多又不能忽略,所以要重写输出流来截取输出,但是遇到了问题
#标准输出劫持类
class Output:
out=io.StringIO() #初始化新的String流
old=sys.stdout #保存之前的标准输出流
def __enter__(self): #with语法糖的入回调
sys.stdout=self.out #劫持输出流
def __exit__(self,etype, evalue, tb): #with语法糖的出回调
sys.stdout=self.old #还原输出流
def get(self): #自定义方法返回劫持期间的输出str
return self.out.getvalue()
out=Output()
with out:
history=model.fit(tranimg, tranvector, epochs=5)#model为tf的模型,执行训练
得到的结果如图所示:
问题在如果训练多代那么输出就会很多,我想把它收缩起来,于是
from IPython.display import HTML
HTML("""<details>
<summary>tensoflow.log</summary>
<p>"""+out.get()+"""</p>"
</details>""")
乍一看很正常,但当我点开tensoflow.log。嗯?怎么和说好的不一样
刚开始以为是python的io.StringIO()未指定编码造成的问题,差点就给cpython提了bug,还好issue页面出了bug无法登陆,不然就丢人了
我重写了一个String流发现字符还是这样的
print打印正常,但是作为字符串使用时异常,突然想起linux的输出重写机制,怀疑TensorFlow的输出是动态输出(进度条的实现方式),因为\x08
是ascii码里的退格符
于是对字符进行模拟打印,简单来说就是遇\x08退格
def simulationPrint(text):
res=[]
for i in text:
if i == "\x08":
res.pop()
else:
res.append(i)
return "".join(res)
simulationPrint(out.get())
没毛病
如果要转HTML这样写
def simulationPrintHTML(text):
res=[]
for i in text:
if i == "\x08": #退格,删除字符
res.pop()
elif i == "\n": #换行符,创建新的行
res.append("<br>")
elif i == "\t": #table 全角空格,约等于4个英文空格
res.append(" ")
elif i == "\r": #回车,使光标到行首
pass
else:
res.append(i)
心态膨胀直接训练120代