栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

如何查看numpy.array()源码?

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何查看numpy.array()源码?

问题描述:在使用numpy是,很好奇下面这段代码是怎么实现的。

import numpy as np

x = np.array([1,2,3])

于是花了点时间来探索,这里记录一下。

在IDE里点开`array`,跳转到一个`_multiarray_umath.pyi`的文件中,这个文件写的密密麻麻,看的一头雾水。如下:

def array(object, dtype=..., *, copy=..., order=..., subok=..., ndmin=..., like=...) -> typing.Any:
    "array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0,n          like=None)nn    Create an array.nn    Parametersn    ----------n    object : array_liken..."

实际上这里只有对`array`的解释说明,并没有源码。因为`.pyi`文件中只存放对函数或类的文档,方便从IDE中查看函数的使用说明。
点开`np`,跳转到`numpy.__init__`文件中,去搜索`array`,只发现在注释中出现了`array`,在代码中一点也没有出现。检查该文件的引用,发现有以下几行代码:

from .core import *
from .lib import *
from .matrixlib import *
__all__.extend(core.__all__)
__all__.extend(_mat.__all__)
__all__.extend(lib.__all__)

在python中,`__all__`限制了`from XX import *` 的范围,上述引用方式只会显示`__all__`中的模块名。也就是说`__init__`中肯定存在`array`,既然没有显示的找到它,那么一定是引用自其他文件的`__all__`变量。首先查找`.core.__init__`,一看这里这么多`*`,这可咋找?

from .numeric import *
from . import fromnumeric
from .fromnumeric import *
from . import defchararray as char
from . import records as rec
from .records import *
from .memmap import *
from .defchararray import chararray
from . import function_base
from .function_base import *
from . import machar
from .machar import *
from . import getlimits
from .getlimits import *
from . import shape_base
from .shape_base import *
from . import einsumfunc
from .einsumfunc import *

网上搜索下了,`numeric`里有绝大部分numpy方法的实现,去看一下`numeric.py`文件,发现有这样一句话:

from .multiarray import (
    _fastCopyAndTranspose as fastCopyAndTranspose, ALLOW_THREADS,
    BUFSIZE, CLIP, MAXDIMS, MAY_SHARE_BOUNDS, MAY_SHARE_EXACT, RAISE,
    WRAP, arange, array, broadcast, can_cast, compare_chararrays,
    concatenate, copyto, dot, dtype, empty,
    empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring,
    inner, int_asbuffer, lexsort, matmul, may_share_memory,
    min_scalar_type, ndarray, nditer, nested_iters, promote_types,
    putmask, result_type, set_numeric_ops, shares_memory, vdot, where,
    zeros, normalize_axis_index)

终于找到了`array`这个单词。。。为啥说是个单词呢?因为只是看到了`array`,并没有看到它的定义。接着去`.multiarray`里找,发现如下语句:

from numpy.core._multiarray_umath import *
from numpy.core._multiarray_umath import (
    _fastCopyAndTranspose, _flagdict, _insert, _reconstruct, _vec_string,
    _ARRAY_API, _monotonicity, _get_ndarray_c_version
    )

__all__ = [
    '_ARRAY_API', 'ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'DATETIMEUNITS',
    'ITEM_HASOBJECT', 'ITEM_IS_POINTER', 'LIST_PICKLE', 'MAXDIMS',
    'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT', 'NEEDS_INIT', 'NEEDS_PYAPI',
    'RAISE', 'USE_GETITEM', 'USE_SETITEM', 'WRAP', '_fastCopyAndTranspose',
    '_flagdict', '_insert', '_reconstruct', '_vec_string', '_monotonicity',
    'add_docstring', 'arange', 'array', 'bincount', 'broadcast',
    'busday_count', 'busday_offset', 'busdaycalendar', 'can_cast',
    'compare_chararrays', 'concatenate', 'copyto', 'correlate', 'correlate2',
    'count_nonzero', 'c_einsum', 'datetime_as_string', 'datetime_data',
    'digitize', 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype',
    'empty', 'empty_like', 'error', 'flagsobj', 'flatiter', 'format_longfloat',
    'frombuffer', 'fromfile', 'fromiter', 'fromstring', 'inner',
    'int_asbuffer', 'interp', 'interp_complex', 'is_busday', 'lexsort',
    'matmul', 'may_share_memory', 'min_scalar_type', 'ndarray', 'nditer',
    'nested_iters', 'normalize_axis_index', 'packbits',
    'promote_types', 'putmask', 'ravel_multi_index', 'result_type', 'scalar',
    'set_datetimeparse_function', 'set_legacy_print_mode', 'set_numeric_ops',
    'set_string_function', 'set_typeDict', 'shares_memory', 'test_interrupt',
    'tracemalloc_domain', 'typeinfo', 'unpackbits', 'unravel_index', 'vdot',
    'where', 'zeros']

这里,在`__all__`字段里找到了`array`,这应该就是我们能在python中找到的最原始的引用了,除此之外再没有其他的关于`array`的定义了。

注意到上面还有一句话是:

from numpy.core._multiarray_umath import *

这个`_multiarray_umath`很眼熟,和最开始在IDE里点开`array`跳转到的文件很像。查看了下`numpy.core`目录,有一个动态链接库文件,在windows中是`_multiarray_umath.cp38-win_amd64.pyd`,在linux中是`_multiarray_umath.cpython-38-x86_64-linux-gnu.so`。
okay,也就是说,`array`是C语言编译后引入的,在我们已经安装的包中是看不到源码的。

那么它具体是从哪里编译过来的呢?
在网上找到了答案:
在这个文件中有它的源码`numpy/core/src/multiarray/multiarraymoudle.c`
搜索`"array"`,注意加双引号,不然只搜索`array`的话有1000多个结果。找到下面这句话:

{"array",
	(PyCFunction)_array_fromobject,
	METH_VARARGS|METH_KEYWORDS, NULL},

意思就是在python中引用的名字叫`array`,是C里面`_array_fromobject`这个函数。在同一个文件里找到这个函数:

static PyObject *
_array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
{
    PyObject *op;
    PyArrayObject *oparr = NULL, *ret = NULL;
    npy_bool subok = NPY_FALSE;
    npy_bool copy = NPY_TRUE;
    int ndmin = 0, nd;
    PyArray_Descr *type = NULL;
    PyArray_Descr *oldtype = NULL;
    NPY_ORDER order = NPY_KEEPORDER;
    int flags = 0;
    ...
}

这就是np.array()真正的源码了,里面用了很多C类型,慢慢研究吧。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966311.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号