2012-11-23 92 views
17

我使用Python的能手探查:http://docs.python.org/2/library/hotshot.htmlPython的统计:我怎么写的(人类可读)文件

它显示了如何打印统计:

stats.print_stats(20) 

但是我怎么弄那成一个文件?我不知道如何获取信息,所以我可以使用write()将它写入文件。

编辑:

我想作为打印时,它的完成这样同样容易阅读的结果:

stats = hotshot.stats.load("stones.prof") 
stats.strip_dirs() 
stats.sort_stats('time', 'calls') 
stats.print_stats(20) 

所以它看起来像这样:

ncalls tottime percall cumtime percall filename:lineno(function) 
    1 3.295 3.295 10.090 10.090 pystone.py:79(Proc0) 

(所以不是因为它看起来像当我打开stones.prof)

回答

2

我最终重写了print_stats()函数,从pstats.py中复制它开始。它返回一个字符串,然后可以将其写入文件。我没有测试过每个if-else循环,只是它在我需要的示例中起作用。我把原来的评论留下了评论。我已经将变量名称保留了,尽管函数不再是“自己”的。

stats = hotshot.stats.load("stones.prof") 
stats.strip_dirs() 
stats.sort_stats('time', 'calls') 
readable_str = xprint_stats(stats, 20) 

import pstats 
def xprint_stats(self, *amount): 
    x = "" 
    for filename in self.files: 
     x += " " + filename 
    #if self.files: print >> self.stream 
    # ? 
    indent = ' ' * 8 
    for func in self.top_level: 
     #print >> self.stream, indent, xfunc_get_function_name(func) 
     x += indent + pstats.func_get_function_name(func) 

    #print >> self.stream, indent, self.total_calls, "function calls", 
    x += indent + str(self.total_calls) + " function calls" + " " 
    if self.total_calls != self.prim_calls: 
     #print >> self.stream, "(%d primitive calls)" % self.prim_calls, 
     x += "(%d primitive calls)" % self.prim_calls + " " 
    #print >> self.stream, "in %.3f seconds" % self.total_tt 
    #print >> self.stream 
    x += "in %.3f seconds" % self.total_tt + "\n" 
    #width, list = stats.get_print_list(amount) 
    msg, width, list = xget_print_list(stats, amount) 
    x += msg 

    if list: 
     #self.print_title() 
     x += "\n" + ' ncalls tottime percall cumtime percall filename:lineno(function)' 
     x += "\n" 
     for func in list: 
      #self.print_line(func) 
      x += xprint_line(self, func) + "\n" 
#  print >> self.stream 
#  print >> self.stream 
    #return self 
    return x 

def xprint_line(self, func): 
    x = "" 
    cc, nc, tt, ct, callers = self.stats[func] 
    c = str(nc) 
    if nc != cc: 
     c = c + '/' + str(cc) 
# print >> self.stream, c.rjust(9), 
# print >> self.stream, f8(tt), 
    x += c.rjust(9) + " " 
    x += pstats.f8(tt) + " " 
    if nc == 0: 
     #print >> self.stream, ' '*8, 
     x += ' '*8 
    else: 
     #print >> self.stream, f8(float(tt)/nc), 
     x += pstats.f8(float(tt)/nc) + " " 
    #print >> self.stream, f8(ct), 
    x += pstats.f8(ct) + " " 
    if cc == 0: 
     #print >> self.stream, ' '*8, 
     x += ' '*8 
    else: 
     #print >> self.stream, f8(float(ct)/cc), 
     x += pstats.f8(float(ct)/cc) + " " 
    #print >> self.stream, func_std_string(func) 
    x += pstats.func_std_string(func) + " " 
    return x 

def xget_print_list(self, sel_list): 
    width = self.max_name_len 
    if self.fcn_list: 
     stat_list = self.fcn_list[:] 
     msg = " Ordered by: " + self.sort_type + '\n' 
    else: 
     stat_list = self.stats.keys() 
     msg = " Random listing order was used\n" 

    for selection in sel_list: 
     stat_list, msg = self.eval_print_amount(selection, stat_list, msg) 

    count = len(stat_list) 

    if not stat_list: 
     return 0, stat_list 
    #print >> self.stream, msg 
    if count < len(self.stats): 
     width = 0 
     for func in stat_list: 
      if len(pstats.func_std_string(func)) > width: 
       width = len(pstats.func_std_string(func)) 
    #return width+2, stat_list 
    return msg, width+2, stat_list 
-1
+2

我试了一下,该文件无法读取。我会编辑我的问题以使其更清楚。 – user984003

+2

你总是可以[将stdout重定向到一个文件](http://stackoverflow.com/questions/6796492/python-temporarily-redirect-stdout-stderr)。 – katrielalex

+0

这不起作用,不是人类可读的。 – marsh

2

输出重定向怎么样?

import sys 
import pstats 
sys.stdout = open('readable.profile', 'w') 
p = pstats.Stats('input.profile') 
p.print_stats() 
30

统计数据采用可选的“流”参数。只需打开一个文件并将打开的文件对象传递给Stats构造函数,如下所示。从这一点开始,任何对print_stats()的调用都会输出到您传递给构造函数的流中。希望这可以帮助。 :)

stream = open('path/to/output', 'w'); 
stats = pstats.Stats('path/to/input', stream=stream) 
stats.print_stats() 
+0

总是很高兴给你的答案增加一些解释,因为自我记录代码并不适合所有人;) – Alexey

+0

对此感到抱歉。我会添加一些。 :) 感谢您的建议。 – Raos

+1

关注代码适用于我:import StringIO; stream = StringIO.StringIO(); stats = pstats.Stats(fname,stream = stream); stats.print_stats(); stream.seek(0);打印stream.read() – moylop260

1

您可以使用库:pstats_print2list https://pypi.python.org/pypi/pstats_print2list

pip install pstats_print2list 与用法:

from pstats_print2list import get_pstats_print2list, print_pstats_list 
fname_stats = 'my_profiling_out.stats' 
pstats_list = get_pstats_print2list(
    os.path.expanduser(fname_stats), 
    filter_fnames=['myfile1.py', 'myfile2.py', 'root_path1'], 
    exclude_fnames=['dontshow.py', 'path_dont_show'], 
    sort='cumulative', 
    limit=5, 
) 
print_pstats_list(pstats_list) 
相关问题