Python多进程CSV转换代码无输出问题排查求助
首先,你的程序没有输出的核心原因是多进程的目标方法参数传递错误,导致子进程在执行convert方法时触发了未被捕获的异常,而子进程的异常不会直接在主进程中显示,所以看起来像是“无任何输出”。
具体问题分析
Imported.convert是一个实例方法,它的第一个参数必须是self(类的实例对象)。但你在创建Process时,直接把Imported.convert作为target,然后把文件名和转换类型作为args传入:
process = Process(target=Imported.convert, args=(filenames[i[0]][0], filenames[i[0]][1]))
这会导致子进程调用convert时,第一个参数是文件名(而不是self实例),参数完全不匹配,直接触发错误,但因为子进程独立运行,这个错误不会反馈到主进程,所以你看不到任何输出或报错。
修正方案
你需要先创建Imported类的实例,然后把实例的convert方法作为多进程的目标(此时方法已经自动绑定了self参数)。修改循环部分的代码即可:
if __name__ == '__main__': filenames = [['data.csv','from_hana'],['klasifikace.csv','to_hana'],['klasifikace_statistiky.csv','to_hana']] processes = [] # 修正后的循环:先创建实例,再绑定实例的convert方法 for filename, convert_type in filenames: # 创建Imported实例 file_converter = Imported(filename, convert_type) # 把实例的convert方法作为target,无需传args(因为已经绑定self) process = Process(target=file_converter.convert) processes.append(process) process.start() for process in processes: process.join() print('DONE')
额外注意事项
子进程输出缓冲问题:即使修正了参数,有时候子进程的
print输出会因为缓冲延迟显示,你可以给print加上flush=True参数,确保即时输出:print(f'Process ID: {process_id}', flush=True) print('test1', flush=True)计时器的问题:当前的
timer函数使用的start_time是主进程定义的变量,在Windows系统(使用spawn启动子进程)中,子进程会重新导入模块,start_time会被重新赋值为子进程启动的时间,导致计时错误。如果需要准确计时,建议在主进程中统一计算总时间,或者给每个子进程传递主进程的启动时间:# 主进程中传递start_time给实例 file_converter = Imported(filename, convert_type, start_time) # 然后在convert方法中使用这个参数计算时间文件覆盖风险:你的代码直接用原文件名保存转换后的文件,可能会在多进程同时操作同一文件时引发冲突(虽然你的示例中是不同文件,但需要注意这个风险)。
修正后运行程序,应该就能看到子进程的输出和最终的DONE提示了。
内容的提问来源于stack exchange,提问作者Dominik Novotný

