代码之家  ›  专栏  ›  技术社区  ›  Pernoctador

Python映射可以复制吗?我需要参考地图

  •  1
  • Pernoctador  · 技术社区  · 9 月前

    我正在编写一个脚本,使用不同的参数多次调用同一函数,然后将结果保存在电子表格(excel)中。为此,我使用了多进程。池,我需要将参数保存在列表中。问题是,当我将参数传递给Pool时,它会得到对象的副本。我假设问题是map(),但我不确定如何解决它。

    以下是一个测试该问题的示例:

    import sys
    import multiprocessing
    import xlwt
    from xlwt import Workbook
    
    def get_prices_in_range(varss):
        row = varss[0]
        col = varss[2]
        start_day = varss[1]
        sheet = varss[3]
        print(sheet)
        try:
            sheet.write(row, col, start_day)
        except:
            pass
    
    if __name__ == '__main__':
           
        # multiprocessing pool object
        pool = multiprocessing.Pool()
        
        # pool object with number of element
        pool = multiprocessing.Pool(processes=2)
    
        #create sheet in excel
        wb = Workbook()
        sheet1 = wb.add_sheet("Sheet 1")
        print(sheet1)
    
        # input list: extend will copy sheet1! not a reference
        inputs = [[x] for x in range(2)]
        for x in inputs:
            x.extend([1, 2, sheet1])
    
        #they've been added by reference:
        print(inputs)
    
        #this doesn't work: sheet1 never gets writen.
        pool.map(get_prices_in_range, inputs)
        # this works:
        #get_prices_in_range([0, 1, 2, sheet1])
        #get_prices_in_range([1, 1, 2, sheet1])
    
    
        wb.save("test.xls")
    

    你可以看到,每一个 打印(页) 显示的对象与 打印(输入) 按原样,如果你发表评论,也一样 pool.map(get_prices_in_range,输入) 并取消注释接下来的2行代码。

    你知道如何解决这个问题吗? 新年快乐!

    1 回复  |  直到 9 月前
        1
  •  1
  •   Pratyush Goutam    9 月前

    问题的产生是因为 multiprocessing.Pool 创建单独的进程,进程之间共享的对象被序列化和反序列化。在此过程中,对原始对象(sheet1)的引用将丢失,因此每个进程都会得到自己的对象副本。

    要解决此问题,您可以使用 multiprocessing.Queue 收集结果。而不是试图直接写信给 sheet1 在worker进程中,您可以让每个进程返回它处理的数据,主进程可以处理写入 表1 .

    以下是应该可以工作的更新代码。我在进行更改的地方添加了注释:

    import multiprocessing
    import xlwt
    from xlwt import Workbook
    
    def get_prices_in_range(varss):
        # Worker function: return the data instead of modifying the sheet
        row, col, start_day = varss[0], varss[1], varss[2]
        return (row, col, start_day)
    
    if __name__ == '__main__':
        pool = multiprocessing.Pool(processes=2)
        
        # Create workbook and sheet in the main process
        wb = Workbook()
        sheet1 = wb.add_sheet("Sheet 1")
    
        # Prepare inputs; removed `sheet1` since workers no longer modify it directly
        inputs = [[x, 1, 2] for x in range(2)]
    
        # Collect results from workers instead of sharing the sheet
        results = pool.map(get_prices_in_range, inputs)
    
        # Write results to the sheet in the main process
        for row, col, start_day in results:
            sheet1.write(row, col, start_day)
    
        wb.save("test.xls")
    

    如果这对你有效,请告诉我。