【问题标题】:Import numpy without installing在不安装的情况下导入 numpy
【发布时间】:2019-12-04 03:05:32
【问题描述】:

有没有办法在不安装的情况下导入numpy

我有一个使用 PyInstaller 内置到 .exe 中的通用应用程序。该应用程序有一个插件系统,允许通过 Python 脚本对其进行扩展。插件导入系统适用于基本模块(单独的 .py 文件、类、函数和简单包)。在内部,它会 glob 一个插件目录,然后使用 __import__importlib.import_module 相应地导入。

应用程序以最小的依赖关系构建,以减少可执行文件的整体大小。此外,不可能知道未来的插件需要哪些依赖项,也不可能包含所有内容。然而,一些插件不可避免地需要依赖。 numpy 是解决这类问题的一个很好的测试用例。


这是我尝试过的。

wheel 文件实际上只是一个目录。可以添加到sys.path并导入内容。

import sys
sys.path.append(r"C:\path\to\numpy-1.16.3+mkl-cp36-cp36m-win_amd64.whl")

import numpy as np

wheel文件被读取,但导入产生错误。

*** ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the multiarray numpy extension module failed.  Most
likely you are trying to import a failed build of numpy.
Here is how to proceed:
- If you're working with a numpy git repository, try `git clean -xdf`
  (removes all files not under version control) and rebuild numpy.
- If you are simply trying to use the numpy version that you have installed:
  your installation is broken - please reinstall numpy.
- If you have already reinstalled and that did not fix the problem, then:
  1. Check that you are using the Python you expect (you're using c:\projects\zip_test\venv\Scripts\python.exe),
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy versions you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log

     Note: this error has many possible causes, so please don't comment on
     an existing issue about this - open a new one instead.

Original error was: No module named 'numpy.core._multiarray_umath'

令人费解的是,wheel 文件包含一个.pyd 代表_multiarray_umath

C:\projects\zip_test\plugins\New folder\numpy\core>dir
 Volume in drive C is OS
 Volume Serial Number is FE3D-6596

 Directory of C:\projects\zip_test\plugins\New folder\numpy\core

07/25/2019  02:37 PM    <DIR>          .
07/25/2019  02:37 PM    <DIR>          ..
    ....
04/22/2019  02:55 AM           101,376 _multiarray_tests.cp36-win_amd64.pyd
04/22/2019  02:55 AM         2,494,976 _multiarray_umath.cp36-win_amd64.pyd
    ....
              74 File(s)    583,173,551 bytes
               5 Dir(s)  309,925,851,136 bytes free

这感觉像是一个路径问题。然而,将core/ 的直接路径添加到sys.path 会产生同样的错误。

sys.path.append(r"C:\projects\zip_test\plugins\numpy-1.16.3+mkl-cp36-cp36m-win_amd64.whl\numpy\core")

有什么关系?为什么Python找不到numpy.core._multiarray_umath


响应回复:

  • 车轮锉从 Christoph Gohlke 处获得。
  • 我的操作系统是 Windows 10 Pro 64 位。
  • 我在venv 中运行Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32(通过Python Foundation build 3.6.8150.0 安装)。 “系统”Python 不在 PATH 上。
  • 我可以通过pipimport numpy as np 安装numpy-1.16.3+mkl-cp36-cp36m-win_amd64.whl 文件,工作正常。然后我通过pip uninstall -y numpy卸载numpy

运行dumpbin /dependents _multiarray_umath.cp36-win_amd64.pyd 产生:

Microsoft (R) COFF/PE Dumper Version 14.22.27905.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file _multiarray_umath.cp36-win_amd64.pyd

File Type: DLL

  Image has the following dependencies:

    mkl_rt.dll
    python36.dll
    KERNEL32.dll
    VCRUNTIME140.dll
    api-ms-win-crt-heap-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-convert-l1-1-0.dll
    api-ms-win-crt-time-l1-1-0.dll
    api-ms-win-crt-utility-l1-1-0.dll
    api-ms-win-crt-locale-l1-1-0.dll

  Summary

       77000 .data
        1000 .gfids
       1C000 .pdata
       30000 .rdata
        3000 .reloc
        1000 .rsrc
      1BD000 .text

在依赖项中,我可以在.whlvenv 中找到mkl_rt.dllpython36.dllVCRUNTIME140.dllKERNEL32.dll 显然有两个版本,一个用于 x86,一个用于 x64。其中之一位于C:\Windows\System32

我能找到的关于 api-ms-win-crt-*.dll 的唯一信息在“Windows 中的通用 C 运行时更新”中的 MSDN 中进行了描述,

Windows 10 通用 CRT 是 Windows 操作系统组件 在 Windows 操作系统上启用 CRT 功能。这 更新允许依赖于 Windows 的 Windows 桌面应用程序 10 通用 CRT 版本,可在早期的 Windows 操作系统上运行。

这些适用于非 Windows 10 系统。似乎没有“官方”的方式来为 Windows 10 系统获取它们。我能够从 Windows 7 系统复制 dll。天真地将它们放在PYTHONPATH 中(不足为奇)是行不通的。如果他们要工作,他们可能需要注册。但是 1) 据我所知,在 Windows 10 上注册 Windows 7 dll 会使系统变得不稳定,并且 2) 绝对不是一个通用的、可移植的解决方案。

【问题讨论】:

  • 第一个问题是 1.) 你从哪里得到的轮子 2.) 你用的是 64 但机器 3.) 你安装了什么 python 版本
  • @EdekiOkoh,好问题!我已经用回复和其他相关信息更新了我的问题。
  • 总是在所有 python 问题中包含通用 [python] 标签。自行决定使用特定于版本的标签。注意,Python 3 Python,Python 2 is rapidly approaching it's end of life。更重要的是,也许是最重要的 Python 项目have pledge to require Python 3

标签: python python-3.x numpy


【解决方案1】:

首先。 使用和不使用 numpy 构建应用程序。检查构建之间的差异。 Original error was: No module named 'numpy.core._multiarray_umath'can意味着两件事:

  1. 找不到文件
  2. 此 pyd 文件的某些依赖性不满足。你可以试试http://dependencywalker.com/查看。

【讨论】:

  • 现在检查。很高兴知道我在正确的轨道上!
  • KERNEL32.dll 是系统站点库。也许您只需要将 numpy whl 复制到程序目录即可正确解决 dll 依赖关系。看列表可能是python36.dll
【解决方案2】:

是的,取决于您如何定义“安装”。

Numpy 需要使用 .pyd 文件。一个 pyd 文件是 essentiallydll。这些是 Python 解释器在运行时引用的编译代码文件。不幸的是,用于加载 dll 文件的 Windows API 调用要求它们存在于文件系统级别。当您尝试直接从轮子导入时,无法访问 pyd 文件(以及它们包含的函数/类)。因此,错误。

(相对)简单的解决方案

一种解决方案是使 pyd 文件在文件系统上可访问。为此,将整个 Wheel 文件解压缩到磁盘1 可能是最简单的。

在这种情况下,请考虑“您如何定义‘安装’”:

  • 如果你可以直接从轮子上运行 numpy,那不就意味着 numpy 已经安装了吗?
  • 无论您是在编写 Wheel 文件还是编写该 Wheel 文件的内容,真正有什么区别?

由于插件系统正在将 Wheel 文件下载到文件系统中,因此应用程序必须具有写入权限。下载wheel文件并将其解压缩到插件目录中。只要插件目录在 PYTHONPATH 上(即sys.path.append),导入就会起作用。可以从那里添加智能等。当然,你需要什么样的智慧是另一个问题。但这是基本思想。

巫师之路

另一种解决方案是创建自己的功能以从内存中导入 dll。这正是 Joachim Bauch 的MemoryModule project 的目标。似乎 Py2Exe 项目通过一个名为 zipextimporter.py 的模块使用了 MemoryModule。不幸的是,代码很难找到并且似乎已经过时(Python 2.4)。还有一个名为pymemimporter.py 的类似模块,它稍微更新一些。


1 Numpy 期望 pyd 文件位于特定位置。如果您只想提取 pyd 文件,则需要将它们嵌套在适当的文件夹中(例如 numpy/core/_multiarray_umath.cp36-win_amd64.pyd)。这足以导入numpy,但除非其他模块可用,否则毫无意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 2019-11-30
    • 2019-11-05
    • 1970-01-01
    相关资源
    最近更新 更多