os 模块是不是在 ProcessPoolExecutor 函数中工作?
Posted
技术标签:
【中文标题】os 模块是不是在 ProcessPoolExecutor 函数中工作?【英文标题】:Does os module work inside ProcessPoolExecutor function?os 模块是否在 ProcessPoolExecutor 函数中工作? 【发布时间】:2020-10-28 00:53:16 【问题描述】:当我运行convert(mp3_files[5])
时,它会按预期创建wav
文件。当我对ProcessPoolExecutor
执行相同操作时,我看到'os' is not defined
异常。怎么了?
import concurrent.futures, subprocess, multiprocessing
def convert(mp3_file):
file_name = os.path.splitext(os.path.basename(mp3_file))[0]
out = os.path.join(audio, file_name + '.wav')
subprocess.run([exe_mpg123, '-q', '-e', 'f32', '-w', out, mp3_file])
def main():
# convert(mp3_files[5])
with concurrent.futures.ProcessPoolExecutor() as executor:
results = executor.map(convert, mp3_files)
for result in results:
print(result)
if __name__ == "__main__":
import os
main()
# Traceback (most recent call last):
# File "C:\script.py", line 159, in <module>
# main()
# File "C:\script.py", line 108, in main
# for result in results:
# File "C:\Users\Asd\miniconda3\lib\concurrent\futures\process.py", line 483, in _chain_from_iterable_of_lists
# for element in iterable:
# File "C:\Users\Asd\miniconda3\lib\concurrent\futures\_base.py", line 598, in result_iterator
# yield fs.pop().result()
# File "C:\Users\Asd\miniconda3\lib\concurrent\futures\_base.py", line 428, in result
# return self.__get_result()
# File "C:\Users\Asd\miniconda3\lib\concurrent\futures\_base.py", line 384, in __get_result
# raise self._exception
# NameError: name 'os' is not defined
os
之前已导入。如果我取消注释 convert(mp3_files[5])
行,它会起作用。
我使用的是 Windows 10 64,Python 3.7.7(默认,2020 年 5 月 6 日,11:45:54)[MSC v.1916 64 bit (AMD64)]。
【问题讨论】:
如果注释掉“subprocess.run(”部分会怎样? 同样的错误。我只能在convert
函数print(os.name)
中放入一行并得到'os' is not defined
错误。
我创建了一个mp3_files
列表和一个audio
规范,删除了对subprocess.run
的调用并从函数convert
返回out
(现在函数返回None
,所以您打印的结果不是特别有趣)并且运行成功。
由于实际问题似乎与 mp3 处理无关,您能否调整您的minimal reproducible example 使其在没有这些部件的情况下工作?这将大大简化试图提供帮助的人的测试。
这就是为什么你应该发布一个 minimal 可重现的例子。还有其他原因。如果您还没有这样做,请阅读链接。它可能比您在此处找到的任何答案更有帮助,因为您还将学习如何自己解决这些问题。
【参考方案1】:
非常感谢您的 cmets,我找到了问题所在。在 Windows 上使用ProcessPoolExecutor
,您必须将您使用的所有导入放在ProcessPoolExecutor
之前 if __name__ == "__main__":
。此代码有效:
import os, concurrent.futures
def convert(mp3_file):
print(os.name)
def main():
mp3_files = [1, 2, 3, 4, 5]
with concurrent.futures.ProcessPoolExecutor() as executor:
results = executor.map(convert, mp3_files)
for result in results:
print(result)
if __name__ == "__main__":
main()
这不是:
import concurrent.futures
def convert(mp3_file):
print(os.name)
def main():
mp3_files = [1, 2, 3, 4, 5]
with concurrent.futures.ProcessPoolExecutor() as executor:
results = executor.map(convert, mp3_files)
for result in results:
print(result)
if __name__ == "__main__":
import os
main()
当您运行一个简单的函数 convert(mp3_files[1])
时,无论您将导入文件放在哪里,它都始终有效。
【讨论】:
以上是关于os 模块是不是在 ProcessPoolExecutor 函数中工作?的主要内容,如果未能解决你的问题,请参考以下文章