You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyCharm运行concurrent.futures官方示例报Pickling错误,Spyder正常

问题原因

Windows系统下,ProcessPoolExecutor使用spawn方式创建子进程,需要将主进程中的函数序列化后传递给子进程。PyCharm的某些运行模式下,脚本的__main__模块结构特殊,导致子进程无法在__main__中找到is_prime函数的定义,从而触发Pickling错误。而Spyder的运行环境会将脚本作为标准模块加载,子进程可以正确解析函数的归属,因此不会报错。

解决方法

方法1:将函数拆分到独立模块(推荐)

把is_prime函数放到单独的Python模块中,主脚本通过导入使用。这样子进程可以直接从模块中导入函数,避免依赖__main__模块的属性查找:

  1. 创建primes.py文件,内容如下:
import math

def is_prime(n):
    if n < 2:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True
  1. 修改主脚本代码,导入该函数:
import concurrent.futures
from primes import is_prime

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

def main():
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()

方法2:调整PyCharm运行配置

确保PyCharm以脚本路径模式运行你的代码,而非模块或交互式模式:

  • 打开Run -> Edit Configurations
  • 在配置列表中找到你的脚本配置
  • 确认Configuration标签下的Script path指向你的脚本文件(而非Module name选项)
  • 点击Apply保存配置后重新运行

方法3:替换默认Pickler为cloudpickle

如果不想拆分模块,可以修改ProcessPoolExecutor的序列化逻辑,使用cloudpickle替代默认的pickle:

import concurrent.futures
import math
import cloudpickle
from concurrent.futures.process import _ProcessPoolExecutor

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

def is_prime(n):
    if n < 2:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True

# 自定义Executor,使用cloudpickle序列化
class CloudPickleExecutor(_ProcessPoolExecutor):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._mp_context.reducer = cloudpickle.reducer

def main():
    with CloudPickleExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()

注意:此方法依赖cloudpickle库,需先通过pip install cloudpickle安装。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 04:08:19