由于numpy包含用C和cython编写的部分,在使用之前需要编译这些部分,请确保安装了必要的编译器和python开发头文件-请参见 从源代码生成 . 从版本开始生成numpy 1.17 需要兼容C99的编译器。
1.17
编译代码还意味着从开发源导入numpy需要一些额外的步骤,下面将解释这些步骤。对于本章的其余部分,我们假设您已按照中所述设置了git repo。 用于开发的Git .
要构建numpy的开发版本并运行测试,使用正确设置的python导入路径生成交互式shell等,请执行以下操作之一:
$ python runtests.py -v $ python runtests.py -v -s random $ python runtests.py -v -t numpy/core/tests/test_nditer.py::test_iter_c_order $ python runtests.py --ipython $ python runtests.py --python somescript.py $ python runtests.py --bench $ python runtests.py -g -m full
这会首先构建 NumPy ,所以第一次可能需要几分钟。如果您指定 -n ,将根据当前pythonpath上找到的numpy(如果有)版本运行测试。
-n
使用指定目标时 -s , -t 或 --python ,可以将其他参数转发到嵌入的目标 runtests.py 通过在 -- . 例如,使用 --pdb 将标志转发到目标,运行以下命令:
-s
-t
--python
runtests.py
--
--pdb
$ python runtests.py -t numpy/tests/test_scripts.py::test_f2py -- --pdb
当使用pytest作为目标(默认)时,可以 match test names using python operators 通过传递 -k pytest的参数:
-k
$ python runtests.py -v -t numpy/core/tests/test_multiarray.py -- -k "MatMul and not vector"
注解
记住,在提交更改之前,NumPy的所有测试都应该通过。
使用 runtests.py 是运行测试的建议方法。它还有许多替代方案,例如就地构建或安装到virtualenv。有关详细信息,请参阅下面的常见问题解答。
测试套件中的某些测试需要大量内存,如果系统内存不足,则会跳过这些测试。
要覆盖对可用内存的自动检测,请设置环境变量 NPY_AVAILABLE_MEM ,例如 NPY_AVAILABLE_MEM=32GB ,或使用pytest --available-memory=32GB 目标选项。
NPY_AVAILABLE_MEM
NPY_AVAILABLE_MEM=32GB
--available-memory=32GB
对于开发,可以设置就地构建,以便对 .py 文件在不重新生成的情况下有效。首先,运行:
.py
$ python setup.py build_ext -i
这允许您导入就地生成的numpy 仅从repo base目录 . 如果希望就地构建在该基目录之外可见,则需要指向 PYTHONPATH 此目录的环境变量。一些IDE (Spyder 例如)要管理实用程序 PYTHONPATH . 在Linux和OSX上,可以运行以下命令:
PYTHONPATH
$ export PYTHONPATH=$PWD
在窗户上:
$ set PYTHONPATH=/path/to/numpy
现在,在numpy中编辑一个python源文件允许您立即测试和使用您的更改(在 .py 文件),只需重新启动解释器。
请注意,另一种在repo base dir外部可见的就地构建方法是 python setup.py develop . 而不是调整 PYTHONPATH ,这将安装一个 .egg-link 将文件保存到网站包中,并调整 easy-install.pth 在那里,这是一个更持久的(和神奇的)操作。
python setup.py develop
.egg-link
easy-install.pth
可以通过运行以下任一命令来发现生成选项:
$ python setup.py --help $ python setup.py --help-commands
可以使用 numpy.distutils 与 -j 选项;见 并行构建 了解更多详细信息。
numpy.distutils
-j
类似的就地构建和使用 PYTHONPATH 但是在源代码树之外使用:
$ pip install . --prefix /some/owned/folder $ export PYTHONPATH=/some/owned/folder/lib/python3.4/site-packages
NumPy使用一系列测试来探测编译器和libc库的函数。结果存储在 _numpyconfig.h 和 config.h 文件使用 HAVE_XXX 定义。这些测试是在 build_src 第二阶段 _multiarray_umath 模块中 generate_config_h 和 generate_numpyconfig_h 功能。由于这些调用的输出包含许多编译器警告和错误,因此默认情况下,它是安静运行的。如果希望看到此输出,可以运行 build_src 详细阐述:
_numpyconfig.h
config.h
HAVE_XXX
build_src
_multiarray_umath
generate_config_h
generate_numpyconfig_h
$ python build build_src -v
一个经常被问到的问题是,“我如何建立一个与发布版本并行的numpy开发版本,我使用它来做我的工作/研究?”.
实现这一点的一个简单方法是在站点包中安装发布的版本,例如使用二进制安装程序或PIP,并在virtualenv中设置开发版本。第一次安装 virtualenv (可选地使用) virtualenvwrapper ,然后使用以下命令创建virtualenv(此处命名为numpy dev):
$ virtualenv numpy-dev
现在,只要您想切换到虚拟环境,就可以使用命令 source numpy-dev/bin/activate 和 deactivate 退出虚拟环境并返回到上一个shell。
source numpy-dev/bin/activate
deactivate
除了使用 runtests.py ,有多种运行测试的方法。在解释器内部,可以这样运行测试:
>>> np.test() >>> np.test('full') # Also run tests marked as slow >>> np.test('full', verbose=2) # Additionally print test name/file An example of a successful test : ``4686 passed, 362 skipped, 9 xfailed, 5 warnings in 213.99 seconds``
或者命令行中的类似方法:
$ python -c "import numpy as np; np.test()"
也可以使用运行测试 pytest numpy 但是,没有找到numpy特定的插件,这会导致奇怪的副作用。
pytest numpy
运行单个测试文件可能很有用;它比运行整个测试套件或整个模块快得多(例如: np.random.test() )这可以通过以下方式完成:
np.random.test()
$ python path_to_testfile/test_file.py
这也需要额外的参数,比如 --pdb 当测试失败或引发异常时,它会将您放入Python调试器。
使用运行测试 tox 也支持。例如,要使用python3.7构建NumPy并运行测试套件,请使用:
$ tox -e py37
有关更广泛的信息,请参阅 测试指南
Note: do not run the tests from the root directory of your numpy git repo without ``runtests.py``, that will result in strange test errors.
对编译代码进行更改后,可以使用与以前相同的生成命令重新生成numpy,只会重新生成更改的文件。执行完整的构建(有时是必需的)需要首先清理工作区。这样做的标准方法是( 注意:删除所有未提交的文件! ):
$ git clean -xdf
当您希望放弃所有更改并返回到repo中的最后一次提交时,请使用以下选项之一:
$ git checkout . $ git reset --hard
另一个常见问题是“如何在NumPy中调试C代码?”。首先,确保在系统上安装了带有Python扩展的gdb(在Linux上通常是默认的)。您可以看到哪个版本的Python正在gdb中运行以验证您的设置:
(gdb) python >import sys >print(sys.version_info) >end sys.version_info(major=3, minor=7, micro=0, releaselevel='final', serial=0)
接下来,您需要编写一个Python脚本来调用要调试其执行的C代码。例如 mytest.py ::
mytest.py
import numpy as np x = np.arange(5) np.empty_like(x)
现在,您可以运行:
$ gdb --args python runtests.py -g --python mytest.py
然后在调试器中:
(gdb) break array_empty_like (gdb) run
现在执行将在相应的C函数处停止,您可以像往常一样逐步执行它。有许多有用的Python特定命令可用。例如,要查看您在Python代码中的位置,请使用 py-list . 有关详细信息,请参阅 DebuggingWithGdb . 以下是一些常用命令:
py-list
list :列出指定的函数或行。 next :Step程序,通过子程序调用继续。 step :在信号或断点后继续正在调试的程序。 print :打印表达式EXP的值。
list :列出指定的函数或行。
list
next :Step程序,通过子程序调用继续。
next
step :在信号或断点后继续正在调试的程序。
step
print :打印表达式EXP的值。
print
而不是平原 gdb 当然,您可以使用您最喜欢的替代调试器;在带有参数的python二进制文件上运行它。 runtests.py -g --python mytest.py .
gdb
runtests.py -g --python mytest.py
使用使用调试支持构建的python构建numpy(在Linux发行版上通常打包为 python-dbg )强烈推荐。
python-dbg
更好地理解代码库的最佳策略是选择您想要更改的内容,然后开始阅读代码,以了解它是如何工作的。如果有疑问,您可以在邮件列表中提出问题。如果你的请求不完美,这是完全可以的,社区总是乐于帮助。作为一个志愿者项目,事情有时会被忽略,如果有什么东西在两到四周内没有回应,打电话给我们完全可以。
所以,继续挑选一些让你烦恼或困惑的关于NumPy的东西,尝试一下代码,四处讨论,或者浏览参考文档来尝试修复它。事情会在适当的地方,很快你就会有一个相当好的项目作为一个整体的理解。祝你好运!