Skip to main content
 首页 » 编程设计

python之可重用函数 : substituting the values returned by another function

2025年05月04日7hnrainll

下面是片段:我正在解析作业日志,输出是格式化的结果。

def job_history(f): 
 
    def get_value(j,n): 
        return j[n].split('=')[1] 
 
    lines = read_file(f) 
    for line in lines: 
        if line.find('Exit_status=') != -1: 
            nLine = line.split(';') 
            jobID = '.'.join(nLine[2].split('.',2)[:-1] 
            jData = nLine[3].split(' ') 
            jUsr = get_value(jData,0) 
            jHst = get_value(jData,9) 
            jQue = get_value(jData,3) 
            eDate = job_value(jData,14) 
 
            global LJ,LU,LH,LQ,LE 
            LJ = max(LJ, len(jobID)) 
            LU = max(LU, len(jUsr)) 
            LH = max(LH, len(jHst)) 
            LQ = max(LQ, len(jQue)) 
            LE = max(LE, len(eDate)) 
 
            print "%-14s%-12s%-14s%-12s%-10s" % (jobID,jUsr,eDate,jHst,jQue) 
 
   return LJ,LU,LE,LH,LQ 

原则上,我应该有另一个这样的功能:

def fmt_print(a,b,c,d,e): 
    print "%-14s%-12s%-14s%-12s%-10s\n" % (a,b,c,d,e) 

打印标题并调用这样的函数来打印完整的结果:

fmt_print('JOB ID','OWNER','E_DATE','R_HOST','QUEUE') 
job_history(inFile) 

我的问题是:如何使用 LJ,LU,LE,LH,LQ 的值使 fmt_print() 打印标题和结果格式间距。 job_history() 将从日志目录中解析大量日志文件。相似类型字段的长度因文件而异,我不想为此保留间距(假设每个字段的最大长度),因为要打印的列要多得多(比示例)。在此先感谢您的帮助。干杯!!

附言。对于那些知道我帖子的人:我不必再使用 python v2.3 了。我什至可以使用 v2.6,但我希望我的代码与 v2.4 兼容,以便默认使用 RHEL5。


更新:1

我的原始脚本中存在一个基本问题。正如我在上面提到的,job_history() 将循环读取目录中的多个文件,max_len 是按文件计算的,而不是针对整个结果计算的。修改后 unutbu 的 脚本并遵循 xtofl 的(如果这是它的意思)建议,我想到了这个,这似乎有效。

def job_history(f): 
    result=[] 
    for line in lines: 
        if line.find('Exit_status=') != -1: 
            .... 
            .... 
            global LJ,LU,LH,LQ,LE 
            LJ = max(LJ, len(jobID)) 
            LU = max(LU, len(jUsr)) 
            LH = max(LH, len(jHst)) 
            LQ = max(LQ, len(jQue)) 
            LE = max(LE, len(eDate)) 
 
            result.append((jobID,jUsr,eDate,jHst,jQue)) 
 
    return LJ,LU,LH,LQ,LE,result 
 
# list of log files  
inFiles = [ m for m in os.listdir(logDir) ] 
 
saved_ary = [] 
for inFile in sorted(inFiles): 
    LJ,LU,LE,LH,LQ,result = job_history(inFile) 
    saved_ary += result 
 
# format printing 
fmt_print = "%%-%ds  %%-%ds  %%-%ds  %%-%ds  %%-%ds" % (LJ,LU,LE,LH,LQ) 
print_head = fmt_print % ('Job Id','User','End Date','Exec Host','Queue') 
print '%s\n%s' % (print_head, len(print_head)*'-') 
 
for lines in saved_ary: 
    print fmt_print % lines 

我相信还有很多其他更好的方法可以做到这一点,因此欢迎提出建议。干杯!!


更新:2

很抱歉再次提出这个“已解决”的帖子。后来发现,我什至连我更新的脚本都错了,所以我想我会发布另一个更新以供将来引用。尽管它看起来工作正常,但实际上 length_data 已被循环中每个文件的新数据覆盖。现在可以正常工作了。

def job_history(f): 
 
    def get_value(j,n): 
        return j[n].split('=')[1] 
 
    lines = read_file(f) 
    for line in lines: 
        if "Exit_status=" in line: 
            nLine = line.split(';') 
            jobID = '.'.join(nLine[2].split('.',2)[:-1] 
            jData = nLine[3].split(' ') 
            jUsr = get_value(jData,0) 
            .... 
 
        result.append((jobID,jUsr,...,....,...)) 
    return result 
 
# list of log files  
inFiles = [ m for m in os.listdir(logDir) ] 
 
saved_ary = [] 
LJ = 0; LU = 0; LE = 0; LH = 0; LQ = 0 
 
for inFile in sorted(inFiles): 
    j_data = job_history(inFile) 
    saved_ary += j_data 
 
for ix in range(len(saved_ary)): 
    LJ = max(LJ, len(saved_ary[ix][0])) 
    LU = max(LU, len(saved_ary[ix][1])) 
    .... 
 
# format printing 
fmt_print = "%%-%ds  %%-%ds  %%-%ds  %%-%ds  %%-%ds" % (LJ,LU,LE,LH,LQ) 
print_head = fmt_print % ('Job Id','User','End Date','Exec Host','Queue') 
print '%s\n%s' % (print_head, len(print_head)*'-') 
 
for lines in saved_ary: 
    print fmt_print % lines 

唯一的问题是开始在屏幕上打印信息需要一些时间,我认为这是因为它首先将所有内容放入数组中,然后再打印。有什么可以改进的吗?干杯!

请您参考如下方法:

因为你不知道LJ, LU, LH, LQ, LE 直到 for 循环结束,您必须在打印之前完成此 for 循环。

    result=[] 
    for line in lines: 
        if line.find('Exit_status=') != -1: 
            ... 
            LJ = max(LJ, len(jobID)) 
            LU = max(LU, len(jUsr)) 
            LH = max(LH, len(jHst)) 
            LQ = max(LQ, len(jQue)) 
            LE = max(LE, len(eDate)) 
            result.append((jobID,jUsr,eDate,jHst,jQue)) 
   fmt="%%-%ss%%-%ss%%-%ss%%-%ss%%-%ss"%(LJ,LU,LE,LH,LQ) 
   for jobID,jUsr,eDate,jHst,jQue in result:        
       print fmt % (jobID,jUsr,eDate,jHst,jQue) 

fmt 行有点棘手。当您使用字符串插值时,每个 %s 都会被一个数字替换,而 %% 会被单个 % 替换。这为后续打印语句准备了正确的格式。