5

numpy没有不安装就可以导入的方法?

我有一个内置于.exePyInstaller 的通用应用程序。该应用程序有一个插件系统,允许通过 Python 脚本对其进行扩展。插件导入系统适用于基本模块(单独的.py文件、类、函数和简单的包)。在内部,它 glob 一个插件目录,然后使用__import__or相应地导入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

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

*** 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'

令人费解的部分是轮文件包含一个.pydfor _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

这感觉像是一个路径问题。然而,添加 to 的直接路径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 位。
  • 我正在运行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)在venv. “系统” Python 不在PATH.
  • 我可以numpy-1.16.3+mkl-cp36-cp36m-win_amd64.whl通过安装文件pip并且import numpy as np工作正常。然后我numpy通过pip uninstall -y 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

在依赖项中mkl_rt.dll,我可以在 the或. 显然有两个版本,一个用于 x86,一个用于 x64。其中之一位于.python36.dllVCRUNTIME140.dll.whlvenvKERNEL32.dllC:\Windows\System32

我能找到的唯一信息api-ms-win-crt-*.dllMSDN中的“Windows 中的 Universal C Runtime 更新”中进行了描述,

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

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

4

2 回答 2

1

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

  1. 找不到文件
  2. 这个 pyd 文件的一些依赖是不满足的。您可以尝试通过http://dependencywalker.com/进行检查。
于 2019-07-25T21:36:41.497 回答
0

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

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

(相对)简单的解决方案

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

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

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

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

巫师之路

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


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

于 2019-08-06T13:25:55.667 回答