【问题标题】:Python - How to read multiple files, process and write to multiple filesPython - 如何读取多个文件、处理和写入多个文件
【发布时间】:2017-05-03 06:12:29
【问题描述】:

我正在尝试在 Python 中构建源代码抄袭检测工具。我正在尝试从输入目录中存在的多个 python 程序文件中获取输入,执行一些处理并将输出写入多个文件。

这是我想要在我的代码中执行的操作:

我有 2 个文件:

  1. ma​​in.py,我在其中打开多个文件并调用我的类和方法
  2. pyscp.py 来自 SoftPlag 包,其中编写了用于处理输入文件的代码。

ma​​in.py

from SoftPlag import *
import os

inputdir = "/path/to/input/directory"
outputdir = "/path/to/output/directory"
filelist = os.listdir(inputdir)

if __name__ == '__main__':   
    for i in filelist:
        with open(inputdir + i, 'r') as f:
            fin = f.read()
            if i.endswith(".py"):
                scp=Pyscp()    
                scp.pscpp(fin)
                f.flush()       
            f.close() 

pyscp.py

这是处理内容所在的文件。每个文件完成后 处理后,将相应的输出写入其文件 输出目录

import re
import keyword
import os

inputdir = "/path/to/input/directory"
outputdir = "/path/to/output/directory"
filelist = os.listdir(inputdir)
frequency={}
class Pyscp():
#Python source-code processing class
    def pscpp(self,fin):
        #remove special characters from string and convert to lower-case 
        char_string=re.sub('[^a-zA-Z._]', ' ', fin).lower()

        #remove single occurrences of characters 
        final_string=re.sub(r'(?:^| )\w(?:$| )', '', char_string).strip() 

        reservedWords={} #empty list to store the reserved keywords
        reservedWords=keyword.kwlist #reserved keywords assigned to reservedWords list

        for word in reservedWords:
            #checking if reserved keyword exists in string or not 
            if word in final_string:
                #substitute reserved keywords with no spaces
                final_string=re.sub(r'\b' + word +r'\b', '', final_string)

            else:
                continue

        for i in filelist:
            file_output = open(os.path.join(outputdir + i +".out"), 'w')
            file_output.write(final_string)
            file_output.close()

我面临的问题是我能够使用 os 包使用单个文件对象打开多个文件并对它们进行处理,但它不能正确写入多个文件。即它是多次写入第一个文件的输出数据,而不是写入不同的输出数据。

请帮忙!

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    您无需再次遍历pyscp.py 中的文件。您正在有效地创建一个嵌套循环,看起来像这样:

    for i_main in filelist:
        # here you are reading your inputfile
        # then you do some processing
        for i_pyscp in filelist:
            # here you are writing to outputfile
    

    这当然会将所有输入文件的所有结果写入所有输出文件。而且由于您使用'w' 属性打开它们,它们被覆盖,只留下外部循环的最终迭代的输出,即filelist 中的最后一个文件。

    我建议删除pyscp.py 中的循环,然后执行return final_string。在main.py 中,您可以将其写入文件。

    另外三个关于main.py的cmets:

    1. 我很惊讶您在open(inputdir + i, 'r') 中没有收到“找不到文件”错误,因为您缺少路径分隔符。 open(os.path.join(inputdir + i), 'r') 将是去这里的方式。

    2. 通常您不需要f.flush(),因为f.close() 会为您处理。此外,您没有将任何数据写入输入文件。

    3. 另外,您不需要 f.close(),因为 with 语句会为您处理。

    【讨论】:

    • 你的意思是说我应该按照上面@ArunKumar的建议在'main.py'中编写函数'pscpp(self,fin)'的代码块吗?关于你提到的三点: 1.我已经按照你的建议实施了。 2 & 3. 我不得不使用 f.flush() 因为我观察到内存清理没有正常进行。如果我试图从 file1.py 和 file2.py 获取输入,它也会从内存中获取 file1.java 的输入,我得到 file1.py、file1.py~、file2.py、file2.py~ & file1 .java~。有什么有效的内存清理方法?
    • 最重要的是在编写输出文件时不要使用循环。如果适合您的需要,您可以将处理部分留在pyscp.py。您也可以将输出文件留在那里,但是您需要在函数调用中传递文件名。我的建议是将文件写入您阅读它们的位置。因此,您的 pyscp.py 将全部与处理有关,您无需担心那里的文件名和路径。那将仅限于您的main.py
    • 关于额外文件:我不明白 Python 为什么会访问这些文件,所以我不知道您的内存问题来自哪里。以~ 结尾的文件名看起来像临时文件,因为一些编辑器创建它们来存储(和恢复)未保存的更改。但根据您的代码,我希望 Python 会忽略它们。
    • 我现在已经将文件的读取和写入放在了我的 main.py 中。因此,通过这些更改,文件读取和写入工作正常。我现在的要求是我需要 pyscp.py 文件中存在的变量“final_string”。该变量存储每个文件的处理输出,需要写入其对应的文件。 'final_string' 变量可以导入到 'main.py' 还是有其他解决方案?
    • 您是在问如何从函数中返回值吗?只需在 pscpp() 函数定义的末尾添加 return final_string。在main.py 中,您可以使用final_string = scp.pscpp(fin) 调用它。
    【解决方案2】:

    我猜想将以下代码块从 'pyscp.py' 文件中的函数 'pscpp()' 移动到 'main.py' 并在函数 'pscpp(self,fin)' 中返回变量 final_string。

    pscpp() 中的这个写入块总是在处理完每个文件后覆盖所有输出文件。这可能是罪魁祸首。

    if __name__ == '__main__':   
        for i in filelist:
            with open(inputdir + i, 'r') as f:
                fin = f.read()
                if i.endswith(".py"):
                    scp=Pyscp()    
                    result = scp.pscpp(fin)
    
                    file_output = open(os.path.join(outputdir + i +".out"), 'w')
                    file_output.write(result)
                    file_output.close()
    
                    f.flush()      
                f.close()
    

    【讨论】:

    • 好的。所以,如果我将'pyscp.py'文件中的代码块放到'main.py'并编写函数'pscpp(self,fin)'和'return(final_string)',我的代码会工作吗?跨度>
    • 是的,我想是的。
    • 好的。我将它们写入函数的动机是我想根据它们的特性将代码块分成函数。我之前提到的处理只是我项目的一部分。我会尝试您的建议,但有什么方法可以根据功能将代码块分开?
    • 您可以在 pscpp() 函数中保留它,唯一的问题是获取文件名的 for 循环。如果可以将其传递给函数 pscpp(),则将其保留在那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 2012-11-27
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    相关资源
    最近更新 更多