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 函数中工作?的主要内容,如果未能解决你的问题,请参考以下文章

常用模块学习os模块详解

Python:使用 os 模块检查目录是不是存在

004---os模块

os模块

python os 模块

为啥使用 Python 的 os 模块方法而不是直接执行 shell 命令?