可重用函数:替换另一个函数返回的值

时间:2011-05-09 11:43:48

标签: python python-2.4

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

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)

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

PS。对于那些了解我帖子的人:我不再需要使用python v2.3了。我甚至可以使用v2.6,但我希望我的代码与v2.4兼容,以符合RHEL5默认值。

<小时/> 更新:1

我的原始脚本存在根本问题。正如我上面提到的,job_history()将读取循环中目录中的多个文件,max_len是按文件计算的,而不是整个结果。修改后 unutbu's脚本稍微按照xtofl's(如果这是它的意思)建议,我想出了这个,这似乎正在起作用。

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

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

3 个答案:

答案 0 :(得分:1)

由于您不知道LJLULHLQLE,直到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都会被一个数字替换,%%会被一个%替换。这为随后的打印语句准备了正确的格式。

答案 1 :(得分:0)

由于列标题和列内容密切相关,为什么不将它们耦合到一个结构中,并从job_history函数返回一个“列”数组?该职能的任务是

  1. 输出每个列的标题
  2. 为每一行创建输出,进入相应的列
  3. 记住每列的最大宽度,并将其存储在struct
  4. 列中

    然后,prinf_fmt函数可以'只是'

    1. 遍历列标题,并使用相应的宽度
    2. 打印它们
    3. 遍历输出的“rest”,使用“相应宽度”
    4. 打印每个单元格

      此设计将输出定义与实际格式分开。

      这是一般的想法。我的蟒蛇不是那么好;但是我可能会在以后想出一些示例代码......

答案 2 :(得分:0)

根据有多少行,您可以:

  • 首先阅读所有内容以找出最大字段长度,然后再次通过这些行来实际打印出结果(如果你只有少数几行)
  • 一次读取一页结果,并计算出接下来30个左右的结果的最大长度(如果你能处理延迟并有很多行)
  • 不关心csv或某种数据库格式的格式和输出 - 让最终的人/实际报告生成者担心导入它