本文分析了在腾讯云的WebIDE中安装Pandas及其依赖文件并部署到Serverless后引用时报错No module named 'numpy.core._multiarray_umath'的原因,并给出了几个应对方法供参考。

一、问题

  阿猪尝试在腾讯云的Serverless中创建一个Python项目,并在这个Python项目中导入Pandas模块。操作步骤如下:

1、创建一个新的Python项目

  在Serverless的函数服务中依次点击“新建” - “从头开始”,各项配置均保持默认,然后点击“完成”按钮。

2、在WebIDE环境中生成依赖文件

  在WebIDE的终端中输入如下命令:

1
2
cd src # 假设当前位于初始位置(项目的根目录)
pip install pandas -t . # 将Pandas模块及其依赖安装到项目的`src`目录`

3、在项目文件中引用Pandas

  以下是一个简单的示例:

1
2
3
4
5
# -*- coding: utf8 -*-
import pandas
def main_handler(event, context):
df = pandas.DataFrame([{'第一列':11,'第二列':12}])
print(df)

4、部署

  在WebIDE中点击“部署”按钮,将项目文件和依赖一起从WebIDE环境上传到Serverless中并完成部署。

5、测试

  在WebIDE中点击“测试”按钮,报错如下:

{“errorCode”:1,”errorMessage”:”Traceback (most recent call last):\n File "/var/runtime/python39/bootstrap.py", line 133, in init_handler\n func_handler = get_func_handler(file.rsplit(".", 1)[0], func)\n File "/var/runtime/python39/bootstrap.py", line 159, in get_func_handler\n mod = imp.load_module(mname, *imp.find_module(mname))\n File "/var/lang/python39/lib/python3.9/imp.py", line 234, in load_module\n return load_source(name, filename, file)\n File "/var/lang/python39/lib/python3.9/imp.py", line 171, in load_source\n module = _load(spec)\n File "\u003cfrozen importlib._bootstrap\u003e", line 711, in _load\n File "\u003cfrozen importlib._bootstrap\u003e", line 680, in _load_unlocked\n File "\u003cfrozen importlib._bootstrap_external\u003e", line 850, in exec_module\n File "\u003cfrozen importlib._bootstrap\u003e", line 228, in _call_with_frames_removed\n File "/var/user/index.py", line 2, in \u003cmodule\u003e\n import pandas\n File "/var/user/pandas/init.py", line 16, in \u003cmodule\u003e\n raise ImportError(\nImportError: Unable to import required dependencies:\nnumpy: \n\nIMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!\n\nImporting the numpy C-extensions failed. This error can happen for\nmany reasons, often due to issues with your setup or how NumPy was\ninstalled.\n\nWe have compiled some common reasons and troubleshooting tips at:\n\n https://numpy.org/devdocs/user/troubleshooting-importerror.html\n\nPlease note and check the following:\n\n * The Python version is: Python3.9 from "/var/lang/python39/bin/python3"\n * The NumPy version is: "1.21.6"\n\nand make sure that they are the versions you expect.\nPlease carefully study the documentation linked above for further help.\n\nOriginal error was: No module named ‘numpy.core._multiarray_umath’\n”,”requestId”:”61e76551-3ea2-432d-a6d9-22e3f65f6161”,”statusCode”:443}

二、原因

  阿猪认为问题的根源是WebIDE环境下生成的Numpy与Serverless实例中的环境不兼容。

  首先,报错信息中提到的numpy.core._multiarray_umath对应的文件路径为/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so(在Windows下则是PYD文件)。SO文件是Linux中编译后的二进制文件,此类文件可能因为编译环境的差异而存在兼容性问题的。结合这个SO文件的名称,阿猪猜测在WebIDE环境中生存的这个SO文件是适用于X86和X64架构Linux的Python3.7的,可能与Serverless实例的Python3.9不兼容。

  其次,在WebIDE的终端执行pip --version,返回结果如下:

pip 23.3.1 from /var/lang/python37/lib/python3.7/site-packages/pip (python 3.7)

  可以看到实际运行的是Python3.7下的pip,这一方面进一步印证了前边的猜测,另一方面也说明阿猪之前直接使用pip命令安装Pandas的方法是错误的,没有考虑到多Python环境的差异。

  进一步的,阿猪尝试修改之前的命令,指定Python3.9的pip来安装Pandas:

1
python3.9 -m pip install pandas -t ./src

  但出乎意料的时,竟然返回了No module named 'pip._internal.operations.build'的报错,也就是说Python3.9的pip无法正常运行。具体报错信息如下:

Traceback (most recent call last):
File “/var/lang/python39/lib/python3.9/runpy.py”, line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File “/var/lang/python39/lib/python3.9/runpy.py”, line 87, in _run_code
exec(code, run_globals)
File “/var/lang/python39/lib/python3.9/site-packages/pip/main.py”, line 31, in
sys.exit(_main())
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/cli/main.py”, line 68, in main
command = create_command(cmd_name, isolated=(“–isolated” in cmd_args))
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/commands/init.py”, line 109, in create_command
module = importlib.import_module(module_path)
File “/var/lang/python39/lib/python3.9/importlib/init.py”, line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File ““, line 1030, in _gcd_import
File ““, line 1007, in _find_and_load
File ““, line 986, in _find_and_load_unlocked
File ““, line 680, in _load_unlocked
File ““, line 850, in exec_module
File ““, line 228, in _call_with_frames_removed
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/commands/install.py”, line 14, in
from pip._internal.cli.req_command import (
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/cli/req_command.py”, line 21, in
from pip._internal.index.package_finder import PackageFinder
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/index/package_finder.py”, line 32, in
from pip._internal.req import InstallRequirement
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/req/init.py”, line 8, in
from .req_install import InstallRequirement
File “/var/lang/python39/lib/python3.9/site-packages/pip/_internal/req/req_install.py”, line 30, in
from pip._internal.operations.build.metadata import generate_metadata
ModuleNotFoundError: No module named ‘pip._internal.operations.build’

三、解决方法

1、将WebIDE中Python3.7里的pip文件复制到Python3.9

  依次执行如下命令,将Python3.9中的pip删除,并使用Python3.7中的pip替代:

1
2
3
4
rm -rf /var/lang/python39/lib/python3.9/site-packages/pip/
rm -rf /var/lang/python39/lib/python3.9/site-packages/pip-22.0.4.dist-info
cp -rf /var/lang/python37/lib/python3.7/site-packages/pip /var/lang/python39/lib/python3.9/site-packages/pip
cp -rf /var/lang/python37/lib/python3.7/site-packages/pip-23.2.dist-info /var/lang/python39/lib/python3.9/site-packages/pip-23.2.dist-info

  完成以上的命令后,就可以正常的使用Python3.9的pip安装Pandas了。
  安装完成后,可以在WebIDE的终端中运行如下命令来测试,正常情况下会返回Numpy的版本号:

1
python3.9 -c "import numpy; print(numpy.__version__)" # 假设当前位于项目的src目录下

2、为WebIDE的Python3.9重新安装pip

1
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3.9 get-pip.py --force-reinstall

3、重新创建项目,将运行环境改为Python3.7或更低。

  在函数服务中新建Python项目时,将运行环境修改为Python3.7或更低版本。

4、不使用WebIDE,使用其他Linux环境来生成依赖文件

  请注意用来生成依赖文件的环境尽量与Serverless的环境保持一致,即 x86架构 + CentOS + Python3.9 。