python把print写入文件_python使用装饰器将函数的print打印写入文件

需求点:设计个装饰器将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

总结:

修改后的代码执行结果永远差两次记录,这个很让我头疼,没找到问题原因在哪儿。。。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值