Python 以正确的顺序从多个线程写入文件

Python 以正确的顺序从多个线程写入文件,python,multithreading,file,Python,Multithreading,File,我试图读入一个文件,使用远程api端点对其进行翻译,然后将其写入一个文件 由于每个请求都需要2-3秒,所以我选择使用线程来加速转换,方法是并行多次命中端点(正如他们的api文档中建议的那样) 然而,我很难想出一个方法来写在正确的顺序翻译行。我想是比赛条件吧。我认为问题在于我正在从多个线程写入单个文件。所以我需要排队什么的,但我不知道怎么接近它 Main() FindMatch() 我认为最简单的解决方案是findMatch将字符串作为参数,并将其翻译作为字符串返回。然后,主程序将负责对所有翻译进

我试图读入一个文件,使用远程api端点对其进行翻译,然后将其写入一个文件

由于每个请求都需要2-3秒,所以我选择使用线程来加速转换,方法是并行多次命中端点(正如他们的api文档中建议的那样)

然而,我很难想出一个方法来写在正确的顺序翻译行。我想是比赛条件吧。我认为问题在于我正在从多个线程写入单个文件。所以我需要排队什么的,但我不知道怎么接近它

Main()

FindMatch()


我认为最简单的解决方案是
findMatch
将字符串作为参数,并将其翻译作为字符串返回。然后,主程序将负责对所有翻译进行排序,并按顺序打印出来


试图同步多个线程(所有线程都写入一个文件)是一个大麻烦。

我认为最简单的解决方案是
findMatch
将字符串作为参数,并将其翻译作为字符串返回。然后,主程序将负责对所有翻译进行排序,并按顺序打印出来


试图同步多个线程并将所有内容写入单个文件是一个大麻烦。

要按正确顺序写入行

  • 使用
    for future in future_to_url
    在提交顺序中迭代未来
  • 使用列表理解
    [execuotr.submit(…)表示f行]
    而不是生成器表达式
    (execuotr.submit(…)表示f行)
    。所有行立即提交给执行者。否则,当循环被迭代时,任务被一个接一个地按需提交,这是不并行的
  • findMatch()
    返回结果,而不是直接写入输出
  • 调用
    future.result()
    时,它会立即返回结果(如果可用),或者阻塞并等待结果

    import concurrent.futures
    导入操作系统
    def main():
    #打开文件
    对于os.listdir(“文件”)中的文件名:
    将open('translate/'+filename,'w',encoding='UTF-8')作为输出文件:
    将open('files/'+filename,'r',encoding='UTF-8')作为f:
    计数=0
    #更换每一行
    以concurrent.futures.ThreadPoolExecutor(max_workers=5)作为执行器:
    #以下内容将提交所有行
    future_to_url=[executor.submit(findMatch,line,count)用于f中的行]
    #完成后返回任意未来
    #使用simple for循环确保未来按顺序迭代
    对于将来的\u到\u url:
    打印(future.result())
    #取消注释以实际写入输出
    #outFile.write(future.result())
    def findMatch(行、计数):
    计数=计数+1#跟踪线路以进行调试
    #检查是否符合要求
    如果(重新搜索(模式1,行)!=无):
    #逐行翻译每一个匹配项。取决于选择
    关于findall中的匹配(模式1,行):
    #过滤掉不带日语的匹配项
    如果(重新搜索(模式2,匹配)!=无且“$”不匹配):
    如果(选项=='1'):
    match=match.rstrip()
    打印('Translating:'+str(count)+':'+match)
    translatedMatch=转换(匹配)
    行=re.sub(匹配,平移匹配,行,1)
    elif(选项='2'):
    match=match.rstrip()
    打印('转换行:'+str(计数))
    直线=平移(直线)
    休息#不要被骗
    其他:
    print('错误的编码器。检查您的if语句')
    回程线
    #跳绳
    其他:
    打印('跳过:'+str(计数))
    回程线
    
    要按正确顺序写入行

  • 使用
    for future in future_to_url
    在提交顺序中迭代未来
  • 使用列表理解
    [execuotr.submit(…)表示f行]
    而不是生成器表达式
    (execuotr.submit(…)表示f行)
    。所有行立即提交给执行者。否则,当循环被迭代时,任务被一个接一个地按需提交,这是不并行的
  • findMatch()
    返回结果,而不是直接写入输出
  • 调用
    future.result()
    时,它会立即返回结果(如果可用),或者阻塞并等待结果

    import concurrent.futures
    导入操作系统
    def main():
    #打开文件
    对于os.listdir(“文件”)中的文件名:
    将open('translate/'+filename,'w',encoding='UTF-8')作为输出文件:
    将open('files/'+filename,'r',encoding='UTF-8')作为f:
    计数=0
    #更换每一行
    以concurrent.futures.ThreadPoolExecutor(max_workers=5)作为执行器:
    #以下内容将提交所有行
    future_to_url=[executor.submit(findMatch,line,count)用于f中的行]
    #完成后返回任意未来
    #使用simple for循环确保未来按顺序迭代
    对于将来的\u到\u url:
    打印(future.result())
    #取消注释以实际写入输出
    #outFile.write(future.result())
    def findMatch(行、计数):
    计数=计数+1#跟踪线路以进行调试
    #检查是否符合要求
    如果(重新搜索(模式1,行)!=无):
    #逐行翻译每一个匹配项。取决于选择
    为比赛在re.fi
    
    #Open File
    for filename in os.listdir("files"):
        with open('translate/' + filename, 'w', encoding='UTF-8') as outFile:
            with open ('files/' + filename, 'r', encoding='UTF-8') as f:
                count = 0
    
                #Replace Each Line
                with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
                    future_to_url = (executor.submit(findMatch, line, count) for line in f)
                    for future in concurrent.futures.as_completed(future_to_url):
                        print(future)
    
    def findMatch(line, count):
        count = count + 1   #Keep track of lines for debugging
        #Check if match in line
        if(re.search(pattern1, line) != None):
    
            #Translate each match in line. Depends on choice
            for match in re.findall(pattern1, line):
    
                #Filter out matches with no Japanese
                if(re.search(pattern2, match) != None and '$' not in match):
                    if(choice == '1'):
                        match = match.rstrip()
                        print('Translating: ' + str(count) + ': ' + match)
                        translatedMatch = translate(match)
                        line = re.sub(match, translatedMatch, line, 1)
    
                    elif(choice == '2'):
                        match = match.rstrip()
                        print('Translating Line: ' + str(count))
                        line = translate(line)
                        break       #Don't want dupes
    
                    else:
                        print('Bad Coder. Check your if statements')
    
            outFile.write(line)
    
        #Skip Line
        else:
            print('Skipping: ' + str(count))
            outFile.write(line)