2013-06-04 53 views
1

我有这个类由3个函数组成。每个功能都负责整个过程的一部分。从其他函数传递值和调用函数

​​加载两个文件,重新格式化它们的内容并将它们写入两个新文件。

.compare()需要两个文件并以特定格式打印出它们的差异。

.final().compare()的结果,并为每组值创建一个文件。

请忽略逻辑的科学怪人性质,因为它目前不是我主要关心的问题。我知道它可以写得好一千倍,现在我还是很好,因为我仍然对Python和编程一般都不熟悉。我确实有一些理论经验,但技术实践非常有限,这正是我正在努力的方向。

下面是代码:

from collections import defaultdict 
from operator import itemgetter 
from itertools import groupby 
from collections import deque 
import os 


class avs_auto: 


    def load(self, fileIn1, fileIn2, fileOut1, fileOut2): 
     with open(fileIn1+'.txt') as fin1, open(fileIn2+'.txt') as fin2: 
      frame_rects = defaultdict(list) 
      for row in (map(str, line.split()) for line in fin1): 
       id, frame, rect = row[0], row[2], [row[3],row[4],row[5],row[6]] 
       frame_rects[frame].append(id) 
       frame_rects[frame].append(rect) 
      for row in (map(str, line.split()) for line in fin2): 
       id, frame, rect = row[0], row[2], [row[3],row[4],row[5],row[6]] 
       frame_rects[frame].append(id) 
       frame_rects[frame].append(rect) 

     with open(fileOut1+'.txt', 'w') as fout1, open(fileOut2+'.txt', 'w') as fout2: 
      for frame, rects in sorted(frame_rects.iteritems()): 
       fout1.write('{{{}:{}}}\n'.format(frame, rects)) 
       fout2.write('{{{}:{}}}\n'.format(frame, rects)) 

    def compare(self, f1, f2): 
     with open(f1+'.txt', 'r') as fin1: 
      with open(f2+'.txt', 'r') as fin2: 
       lines1 = fin1.readlines() 
       lines2 = fin2.readlines() 
       diff_lines = [l.strip() for l in lines1 if l not in lines2] 
       diffs = defaultdict(list) 
       with open(f1+'x'+f2+'Result.txt', 'w') as fout: 
        for line in diff_lines: 
         d = eval(line) 
         for k in d: 
          list_ids = d[k] 
          for i in range(0, len(d[k]), 2): 
           diffs[d[k][i]].append(k) 
        for id_ in diffs: 
         diffs[id_].sort() 
         for k, g in groupby(enumerate(diffs[id_]), lambda (i, x): i - x): 
          group = map(itemgetter(1), g) 
          fout.write('{0} {1} {2}\n'.format(id_, group[0], group[-1])) 

    def final(self): 
     with open('hw1load3xhw1load2Result.txt', 'r') as fin: 
      lines = (line.split() for line in fin) 
      for k, g in groupby(lines, itemgetter(0)): 
       fst = next(g) 
       lst = next(iter(deque(g, 1)), fst) 
       with open('final/{}.avs'.format(k), 'w') as fout: 
        fout.write('video0=ImageSource("MovieName\original\%06d.jpeg", {}, {}, 15)\n'.format(fst[1], lst[2])) 

现在我的问题,我该如何使它所以每一个函数传递它的输出文件作为值到下一个功能,并调用它?

因此,对于一个例子:

运行​​应该输出两个文件,调用.compare()函数传递这两个文件。

然后当.compare()完成后,它应该通过.final()输出文件并调用它。

因此,.final()将打开从.compare()传递给它的任何文件,而不是如上所定义的"test123.txt"

我希望这一切都有道理。让我知道你是否需要澄清。对于代码本身,任何批评都是值得欢迎的。提前致谢。

回答

3

有几种方法可以做到这一点,但是我会编写一个主函数来依次调用其他三个函数。例如:

def load_and_compare(self, input_file1, input_file2, output_file1, output_file2, result_file): 
    self.load(input_file1, input_file2, output_file1, output_file2) 
    self.compare(output_file1, output_file2) 
    self.final(result_file) 

查看您的代码,我认为您在加载时遇到问题。你只声明一个字典,然后将两个文件的内容加载到它中,并将这些内容写入两个文件。由于每个文件具有相同的内容,比较不会做任何有意义的事情。

另外,你真的想写出文件内容,然后重新读入内存吗?我会保持框架定义在内存中,以便在加载后使用,而不是将它们读回来。

我真的不认为这是一个类的原因,而不仅仅是三个函数,但也许如果你必须读取多种格式不同的文件,你可以在继承一般逻辑的同时使用类属性来定义格式。

+0

是的,你对我的负载的问题是正确的,我修好了,谢谢!我唯一的问题是,我如何通过open()行将“result_file”传递给final?如果我这样做:“打开(result_file +'。txt','r')为fin:”它返回“没有这样的文件或目录”。你有可能把我指向正确的方向吗? – MaxPower

+1

那么,那个错误意味着它没有找到预期的文件 - 你需要确认它存在于你提供的位置。如果这意味着来自'compare'的输出,那么我可能会在master函数中构建我期望的文件名,并将它作为参数传递给'compare'和'final',以确保它们。 –

3

你的意思是跟两个文件的名字叫?那么你定义了一个类,所以你可以这样做:

def load(self, fileIn1, fileIn2, fileOut1, fileOut2): 
    ... // do stuff here 
    // when done 
    self.compare(fileOut1, fileOut2) 

依此类推。

1

我可能完全不在这里,但为什么不按照你所说的去做呢?

只需拨打self.compare()load()方法。

您还可以将返回语句添加到load()并返回一个tuple与文件。

然后向你的班级添加第四种方法,然后收集返回的文件,并将它们传送给compare()方法。

最好的问候!

1

Python的一个更强大的方面是你可以返回一个叫tuple的东西。要在更一般的Python的感觉回答这个考虑下面的代码:

>>> def load(file1, file2): 
     return file1+'.txt',file2+'.txt' 

>>> def convert(file1, file2): 
     return 'converted_'+file1,'converted_'+file2 

>>> convert(*load("Java", "C#")) 
('converted_Java.txt', 'converted_C#.txt') 

每个函数有两个命名的参数,但第一个返回的元组可以“解包”进入第二个的输入参数通过添加*在它前面。