需求点:设计个装饰器将print输出保存到日志中
import os
import sys
import threading
import time
from functools import wraps
#指定日志路径
logpath = os.path.join(os.path.dirname(__file__), 'log.txt')
def save_print_to_log(act_def):
def wrapper(*args, **kwargs):
#将打印临时保存
sys.stdout = open('temp.txt', 'w', encoding='utf-8')
act_def(*args, **kwargs)
sys.stdout.close()
with open('temp.txt', 'r', encoding='utf-8')as tmp:
with open(logpath, 'a+', encoding='utf-8')as fp:
#写入日志的格式
fp.write('[{}][{}]:{}'.format(time.strftime('%Y-%m-%d %X'), act_def.__name__,tmp.read()))
return wrapper
@save_print_to_log
def get_log():
print('这个一个日志打印')
四次执行结果:
[2020-09-19 23:18:48]这个一个日志打印
[2020-09-19 23:19:01]这个一个日志打印
[2020-09-19 23:22:14]这个一个日志打印
[2020-09-19 23:22:27]这个一个日志打印
小结:
这个装饰器对多线程支持不友好,以下是我添加线程锁之后的代码,貌似还不理想,自己感觉是线程用的不合适,但还没想到好的解决办法,请大佬们看到的话分享些建议,不胜感激!
import os
import sys
import threading
import time
from functools import wraps
logpath = os.path.join(os.path.dirname(__file__), 'log.txt')
def count_time(act_def):
@wraps(act_def)
def _count():
start_time = time.time()
with open(logpath, 'a', encoding='utf-8')as pf:
pf.write('开始...\n')
act_def()
end_time = time.time()
with open(logpath, 'a', encoding='utf-8')as pf:
pf.write('结束!\n耗时:%s' % (end_time - start_time))
return _count
going = threading.Lock()
def save_print_to_log(act_def):
def wrapper(*args, **kwargs):
global going
with going:
sys.stdout = open('temp.txt', 'w+', encoding='utf-8')
act_def(*args, **kwargs)
sys.stdout.close()
with open('temp.txt', 'r', encoding='utf-8')as tmp:
with open(logpath, 'a', encoding='utf-8')as fp:
fp.write('[{}][{}]:{}'.format(time.strftime('%Y-%m-%d %X'), act_def.__name__, tmp.read()))
return wrapper
@save_print_to_log
def get_log1():
print('这是函数1日志')
@save_print_to_log
def get_log2():
print('这是函数2日志')
@count_time
def try_test1():
cout = 0
for i in range(0, 5):
cout += 1
time.sleep(0.5) # 线程启动太快会乱,应该是文件来不及关闭导致的
t = threading.Thread(target=get_log1, )
t2 = threading.Thread(target=get_log2, )
t.setDaemon(True)
t2.setDaemon(True)
t.start()
t2.start()
with open(logpath, 'a', encoding='utf-8')as fp:
fp.write(str(cout)+'次执行\n')
try_test1()
测试结果:
开始...
[2020-09-20 17:06:46][get_log1]:这是函数1日志
[2020-09-20 17:06:46][get_log2]:这是函数2日志
[2020-09-20 17:06:46][get_log1]:这是函数1日志
[2020-09-20 17:06:46][get_log2]:这是函数2日志
[2020-09-20 17:06:47][get_log1]:这是函数1日志
[2020-09-20 17:06:47][get_log2]:这是函数2日志
[2020-09-20 17:06:47][get_log1]:这是函数1日志
[2020-09-20 17:06:47][get_log2]:这是函数2日志
5次执行
结束!
耗时:2.506901264190674
总结:
修改后的代码执行结果永远差两次记录,这个很让我头疼,没找到问题原因在哪儿。。。