简 介: 本文原本是为了能够寻找一种可以将AI Studio程序输出的文本快速传送到Windows的方法,现在使用printt替代原来的print进行相应的程序调试。
关键词
: print,printt,aistudio
§01 stdout存储文件
1.1 背景介绍
由于需要在AI Studio中进行深度学习程序开发。如何能够进行快速信息交互呢?
这部分可以借助于Windows Clipboard进行信息交换。现在已经基于此可以将Windows下的TEASOFT程序快速粘贴到AI Studio Notebook进行执行。今天寻找到一个机制,可以将AI Studio的输出快速取出。
1.1.1 Studio快速获得输出结果?
这其中最主要的原因就是用于记录程序调试过程。本质上讲,可以通过简单的鼠标选择,拷贝即可。但这个过程过于繁琐。希望能够抛开鼠标,加快文本的获取。
▲ 图1.1.1 AI Studio 程序执行输出结果
1.1.2 解决方案
解决方案的基本原理是:
- 在 AI Studio中,可以将输出暂存在 /home/aistudio/work/stdout.txt中。这个文件是随意定义的;
- 通过AIStudio,可以点击该文件,通过Explore打开;
- 在打开的Explorer窗口中,可以通过 CTRL+R来更新该文件;可以通过CTRL+A,C拷贝到Windows的Clipboard,从而可以为后续处理提供条件。
这个过程,就不在需要使用鼠标进行操作了。
(1)增加printt函数
标准的程序输出都是通过print,现在修改成printt()。它的主要功能为:
with open('/home/aistudio/work/stdout.txt','w') as f: pass
def printt(*args, **kwargs):
with open('/home/aistudio/work/stdout.txt','a') as f:
for a in args: f.write(str(a)+'\n'), print(a)
在 ais 程序将Windows下的编辑器程序加载到AI Studio的过程中,如果判断其中存在 printt,则在执行代码前增加上述附加的定义函数部分。它可以:
- 将原来的stdio.txt进行清空;
- 提供printt函数的定义;
所有希望能够快速去除的信息输出,都通过printt进行输出。
1.1.3 cdpc改动
(1)对printt进行改变
对于CSDN粘贴过程中,将printt改变成 print
(2)命令
这个命令模拟对STDOUT浏览器窗口的操作:
- CTRL+R:刷新浏览器窗口;
- CTRL+A:选择所有的内容;
- CTRL+C:拷贝到内存。
将内存内容发送到 CSDN。
§02 Python函数修饰符
Python
函数修饰符@
的作用是为现有的函数增加额外的功能;其作用非常强大,今天我们就来谈谈它是如何在日志记录中起到很好的作用的。
2.1 举例说明
2.1.1 测试代码
import datetime
__DEBUG__ = True
def log(func):
if __DEBUG__:
print("Begin:{}".format(datetime.datetime.now()))
func()
if __DEBUG__:
print('End: {}'.format(datetime.datetime.now()))
def test():
print("Test")
test_list = []
for i in range(100):
test_list.append(i)
log(test)
Begin:2021-12-19 17:20:04.001836
Test
End: 2021-12-19 17:20:04.002194
log()
是一个日志函数,用于记录函数运行的开始时间,和结束时间。
可是这段代码有个弊端,在测试某个函数时,我们需要添加类似于log(test)
这样的代码,不需要后把它删除;这样做很麻烦。
还好我们有@
函数装饰符。修改前文中的代码,移除 log(text).
在test
函数的上方加入@log
装饰器。
2.1.2 使用函数装饰符
import datetime
__DEBUG__ = True
def log(func):
if __DEBUG__:
print("Begin:{}".format(datetime.datetime.now()))
func()
if __DEBUG__:
print('End: {}'.format(datetime.datetime.now()))
@log
def test():
print("Test")
test_list = []
for i in range(100):
test_list.append(i)
Begin:2021-12-19 17:21:49.722388
Test
End: 2021-12-19 17:21:49.722700
这段代码和前文中的代码功能是一样的。
可是问题又来了;运行上述代码,发现我们没有调用 test
函数,test
就已经被执行了,因为 @log
等于 log(test)
,有什么方法让它只有在我们调用的时候运行呢?修改代码:
我在log
函数中定义了一个wrapper
函数对原功能进行包装,并将这个函数返回。
在不使用装饰器的情况下,你需要这样才能让函数运行:
log(test)
在使用@log
装饰器后,直接调用test()
即可获取函数运行日志,我们可以为很多需要测试的函数添加@log
装饰器,不需要用这个功能直接将__DEBUG__
设置成 False
。
它的执行顺序是这样的:在为函数添加了@log
装饰器后,log
函数就被执行,而使用了@log
装饰器的 test
函数被作为log
函数的传入值使用,在log
函数中,对test
函数进行了一个简单的包装,并将包装好的函数返回,也就是log
函数中的wrapper
函数;此时test
函数实际变成了 wrapper
函数。
2.2 增加函数参数
2.2.1 函数的参数
前文中的 test 函数是没有使用参数的,如果你要定义和使用参数,应该这样修改:
def log(func):
def wrapper(*args, **kwargs):
if __DEBUG__:
print("Begin: {}".format(datetime.datetime.now()))
func(*args, **kwargs)
if __DEBUG__:
print("End :{}".format(datetime.datetime.now))
return wrapper
*args是将参数以元组的形式打包成tuple
给函数体调用;
**kwargs是将关键字参数打包成dict给函数体调用;
2.2.2 log增加参数
有这样一个场景:
fp = open('out.log','a')
@log(level=1,file=fp)
@log(1,fp)
怎么能让装饰器拥有参数呢?
import datetime
import sys
__DEBUG__ = True
class _log:
def __call__(self,level=1,file=sys.stdout):
def _log_wrapper(func):
def wrapper(*args,**kwargs):
if __DEBUG__:
print('函数开始于',datetime.datetime.now(),file=file,flush=True)
func(*args,**kwargs)
if __DEBUG__:
print('函数结束于',datetime.datetime.now(),file=file,flush=True)
return wrapper
return _log_wrapper
def sendto(self,addr,timeout=20):
pass
log=_log()
fp = open('out.log','a')
@log(file=fp)
def test(a,b):
print('test')
test_lst = []
for i in range(a):
test_lst.append(i*b)
test(1,2)
§03 总 结
本文原本是为了能够寻找一种可以将AI Studio程序输出的文本快速传送到Windows的方法,现在使用printt替代原来的print进行相应的程序调试。
● 相关图表链接: