NumPy 源码解析(五)

.\numpy\doc\source\user\plots\matplotlib3.py

# 导入 NumPy 库,通常用于处理数组和数值计算
import numpy as np
# 导入 Matplotlib 的 pyplot 模块,用于绘图操作
import matplotlib.pyplot as plt

# 创建一个新的图形对象
fig = plt.figure()
# 在图形对象上添加一个三维坐标系的子图
ax = fig.add_subplot(projection='3d')

# 生成一个 X 轴上的坐标数组,范围从 -5 到 5,步长为 0.15
X = np.arange(-5, 5, 0.15)
# 生成一个 Y 轴上的坐标数组,范围从 -5 到 5,步长为 0.15
Y = np.arange(-5, 5, 0.15)
# 将 X 和 Y 坐标数组转换成网格形式
X, Y = np.meshgrid(X, Y)
# 计算每个网格点的极径 R
R = np.sqrt(X**2 + Y**2)
# 计算每个网格点的 Z 值,使用 sin 函数作为高度值
Z = np.sin(R)

# 在三维坐标系上绘制一个表面图,使用 viridis 颜色映射
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis')

# 显示绘制的图形
plt.show()

.\numpy\doc\source\user\plots\meshgrid_plot.py

# 导入 NumPy 库,用于科学计算
import numpy as np
# 导入 Matplotlib 库中的 pyplot 模块,用于绘图
import matplotlib.pyplot as plt

# 创建 NumPy 数组 x 和 y,分别表示 x 和 y 轴上的坐标点
x = np.array([0, 1, 2, 3])
y = np.array([0, 1, 2, 3, 4, 5])

# 使用 meshgrid 函数生成网格数据,xx 和 yy 是网格化后的 x 和 y 值
xx, yy = np.meshgrid(x, y)

# 使用 Matplotlib 的 pyplot 模块绘制散点图
plt.plot(xx, yy, marker='o', color='k', linestyle='none')

.\numpy\numpy\char\__init__.py

# 导入 numpy._core.defchararray 模块中的 __all__ 和 __doc__ 变量
from numpy._core.defchararray import __all__, __doc__
# 导入 numpy._core.defchararray 模块中的所有函数和变量
from numpy._core.defchararray import *

.\numpy\numpy\char\__init__.pyi

# 从 numpy._core.defchararray 模块中导入一系列字符串操作函数,用于操作字符数组

from numpy._core.defchararray import (
    equal as equal,                     # 别名 equal,用于比较两个字符数组是否相等
    not_equal as not_equal,             # 别名 not_equal,用于比较两个字符数组是否不相等
    greater_equal as greater_equal,     # 别名 greater_equal,用于比较字符数组左侧是否大于等于右侧
    less_equal as less_equal,           # 别名 less_equal,用于比较字符数组左侧是否小于等于右侧
    greater as greater,                 # 别名 greater,用于比较字符数组左侧是否大于右侧
    less as less,                       # 别名 less,用于比较字符数组左侧是否小于右侧
    str_len as str_len,                 # 别名 str_len,返回字符数组中每个字符串的长度
    add as add,                         # 别名 add,用于字符数组的逐元素相加
    multiply as multiply,               # 别名 multiply,用于字符数组的逐元素相乘
    mod as mod,                         # 别名 mod,用于字符数组的逐元素取模运算
    capitalize as capitalize,           # 别名 capitalize,将字符数组中每个字符串的首字母大写
    center as center,                   # 别名 center,将字符数组中每个字符串居中对齐
    count as count,                     # 别名 count,统计字符数组中每个字符串出现的次数
    decode as decode,                   # 别名 decode,解码字符数组中的每个字符串
    encode as encode,                   # 别名 encode,编码字符数组中的每个字符串
    endswith as endswith,               # 别名 endswith,判断字符数组中每个字符串是否以指定后缀结尾
    expandtabs as expandtabs,           # 别名 expandtabs,将字符数组中每个字符串的制表符扩展为空格
    find as find,                       # 别名 find,查找字符数组中每个字符串第一次出现的位置
    index as index,                     # 别名 index,查找字符数组中每个字符串第一次出现的位置
    isalnum as isalnum,                 # 别名 isalnum,判断字符数组中每个字符串是否由字母和数字组成
    isalpha as isalpha,                 # 别名 isalpha,判断字符数组中每个字符串是否只包含字母
    isdigit as isdigit,                 # 别名 isdigit,判断字符数组中每个字符串是否只包含数字
    islower as islower,                 # 别名 islower,判断字符数组中每个字符串是否全为小写字母
    isspace as isspace,                 # 别名 isspace,判断字符数组中每个字符串是否只包含空白字符
    istitle as istitle,                 # 别名 istitle,判断字符数组中每个字符串是否遵循标题化规则
    isupper as isupper,                 # 别名 isupper,判断字符数组中每个字符串是否全为大写字母
    join as join,                       # 别名 join,将字符数组中每个字符串用指定分隔符连接成一个字符串
    ljust as ljust,                     # 别名 ljust,将字符数组中每个字符串左对齐,并用空格填充至指定长度
    lower as lower,                     # 别名 lower,将字符数组中每个字符串转换为小写
    lstrip as lstrip,                   # 别名 lstrip,将字符数组中每个字符串左侧的空白字符删除
    partition as partition,             # 别名 partition,将字符数组中每个字符串按照第一次出现的分隔符分为三部分
    replace as replace,                 # 别名 replace,将字符数组中每个字符串的指定子串替换为新的子串
    rfind as rfind,                     # 别名 rfind,查找字符数组中每个字符串最后一次出现的位置
    rindex as rindex,                   # 别名 rindex,查找字符数组中每个字符串最后一次出现的位置
    rjust as rjust,                     # 别名 rjust,将字符数组中每个字符串右对齐,并用空格填充至指定长度
    rpartition as rpartition,           # 别名 rpartition,将字符数组中每个字符串按照最后一次出现的分隔符分为三部分
    rsplit as rsplit,                   # 别名 rsplit,将字符数组中每个字符串按照指定分隔符从右向左分割
    rstrip as rstrip,                   # 别名 rstrip,将字符数组中每个字符串右侧的空白字符删除
    split as split,                     # 别名 split,将字符数组中每个字符串按照指定分隔符分割
    splitlines as splitlines,           # 别名 splitlines,将字符数组中每个字符串按照行分割
    startswith as startswith,           # 别名 startswith,判断字符数组中每个字符串是否以指定前缀开头
    strip as strip,                     # 别名 strip,将字符数组中每个字符串两侧的空白字符删除
    swapcase as swapcase,               # 别名 swapcase,将字符数组中每个字符串的大小写互换
    title as title,                     # 别名 title,将字符数组中每个字符串转换为标题化形式
    translate as translate,             # 别名 translate,根据字符映射表对字符数组中每个字符串进行转换
    upper as upper,                     # 别名 upper,将字符数组中每个字符串转换为大写
    zfill as zfill,                     # 别名 zfill,将字符数组中每个字符串左侧填充零到指定宽度
    isnumeric as isnumeric,             # 别名 isnumeric,判断字符数组中每个字符串是否只包含数字字符
    isdecimal as isdecimal,             # 别名 isdecimal,判断字符数组中每个字符串是否只包含十进制数字字符
    array as array,                     # 别名 array,创建一个字符数组对象
    asarray as asarray,                 # 别名 asarray,将输入转换为字符数组对象
    compare_chararrays as compare_chararrays,  # 别名 compare_chararrays,比较两个字符数组对象
    chararray as chararray              # 别名 chararray,字符数组对象类型
)

__all__: list[str]                      # 定义变量 __all__,包含在 from ... import * 语句中应导入的公共名称列表

.\numpy\numpy\compat\py3k.py

"""
Python 3.X compatibility tools.

While this file was originally intended for Python 2 -> 3 transition,
it is now used to create a compatibility layer between different
minor versions of Python 3.

While the active version of numpy may not support a given version of python, we
allow downstream libraries to continue to use these shims for forward
compatibility with numpy while they transition their code to newer versions of
Python.
"""
__all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar',
           'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested',
           'asstr', 'open_latin1', 'long', 'basestring', 'sixu',
           'integer_types', 'is_pathlib_path', 'npy_load_module', 'Path',
           'pickle', 'contextlib_nullcontext', 'os_fspath', 'os_PathLike']

import sys                              # 导入 sys 模块,用于访问系统相关功能
import os                               # 导入 os 模块,用于访问操作系统功能
from pathlib import Path                # 导入 Path 类,用于处理路径操作
import io                               # 导入 io 模块,用于处理文件流操作

try:
    import pickle5 as pickle            # 尝试导入 pickle5 库,若不成功则导入标准的 pickle 库
except ImportError:
    import pickle                       # 如果导入 pickle5 失败,导入标准的 pickle 库

long = int                              # 定义 long 为 int 类型,用于兼容 Python 3 中移除的 long 类型
integer_types = (int,)                  # 定义 integer_types 为包含 int 的元组,用于兼容 Python 2/3 整数类型的差异
basestring = str                        # 定义 basestring 为 str 类型,用于兼容 Python 2/3 中字符串类型的差异
unicode = str                           # 定义 unicode 为 str 类型,用于兼容 Python 2/3 中的字符串类型
bytes = bytes                           # 定义 bytes 为 bytes 类型,用于兼容 Python 2/3 中的字节类型

def asunicode(s):
    if isinstance(s, bytes):
        return s.decode('latin1')       # 如果 s 是 bytes 类型,则解码为 str 类型,使用 Latin-1 编码
    return str(s)                       # 否则直接转换为 str 类型

def asbytes(s):
    if isinstance(s, bytes):
        return s                        # 如果 s 已经是 bytes 类型,则直接返回
    return str(s).encode('latin1')      # 否则将 s 转换为 str 类型后再编码为 bytes 类型,使用 Latin-1 编码

def asstr(s):
    if isinstance(s, bytes):
        return s.decode('latin1')       # 如果 s 是 bytes 类型,则解码为 str 类型,使用 Latin-1 编码
    return str(s)                       # 否则直接转换为 str 类型

def isfileobj(f):
    if not isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter)):
        return False                    # 如果 f 不是文件对象类型,则返回 False
    try:
        f.fileno()                      # 尝试获取文件描述符,可能会抛出 OSError 异常
        return True                     # 如果成功获取文件描述符,则返回 True
    except OSError:
        return False                    # 获取文件描述符失败,返回 False

def open_latin1(filename, mode='r'):
    return open(filename, mode=mode, encoding='iso-8859-1')  # 使用 Latin-1 编码打开指定文件

def sixu(s):
    return s                            # 返回参数 s,用于兼容性,不进行额外处理

strchar = 'U'                           # 定义 strchar 为 'U'

def getexception():
    return sys.exc_info()[1]            # 返回当前异常信息的第一个元素,即异常对象

def asbytes_nested(x):
    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
        return [asbytes_nested(y) for y in x]  # 如果 x 是可迭代对象且不是 bytes 或 unicode 类型,则递归处理每个元素
    else:
        return asbytes(x)               # 否则将 x 转换为 bytes 类型并返回

def asunicode_nested(x):
    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
        return [asunicode_nested(y) for y in x]  # 如果 x 是可迭代对象且不是 bytes 或 unicode 类型,则递归处理每个元素
    else:
        return asunicode(x)             # 否则将 x 转换为 unicode 类型并返回

def is_pathlib_path(obj):
    """
    Check whether obj is a `pathlib.Path` object.

    Prefer using ``isinstance(obj, os.PathLike)`` instead of this function.
    """
    return isinstance(obj, Path)        # 检查 obj 是否为 pathlib.Path 对象

# from Python 3.7
class contextlib_nullcontext:
    """Context manager that does no additional processing.

    Used as a stand-in for a normal context manager, when a particular
    block of code is only sometimes used with a normal context manager:

    cm = optional_cm if condition else nullcontext()
    with cm:
        # Perform operation, using optional_cm if condition is True

    .. note::
        Prefer using `contextlib.nullcontext` instead of this context manager.
    """

    def __init__(self, enter_result=None):
        self.enter_result = enter_result  # 初始化上下文管理器,保存进入结果
    # 定义上下文管理器的进入方法,当使用 with 语句时执行
    def __enter__(self):
        # 返回上下文管理器的进入结果,通常是为了与 as 关键字后的变量进行绑定
        return self.enter_result

    # 定义上下文管理器的退出方法,当退出 with 语句块时执行
    def __exit__(self, *excinfo):
        # 占位符方法体,不做任何实际操作,即使在异常发生时也不处理异常
        pass
# 加载一个模块。使用 ``load_module`` 方法,该方法将在 Python 3.12 中被弃用。
# 另外,可以使用 ``exec_module`` 方法,该方法在 numpy.distutils.misc_util.exec_mod_from_location 中定义。

# .. versionadded:: 1.11.2
# 版本添加说明,从版本 1.11.2 开始可用。

# Parameters
# ----------
# name : str
#     完整的模块名称。
# fn : str
#     模块文件的路径。
# info : tuple, optional
#     仅用于向后兼容 Python 2.*。

# Returns
# -------
# mod : module
#     加载并返回的模块对象。

def npy_load_module(name, fn, info=None):
    # 显式延迟导入以避免在启动时导入 importlib 的开销
    from importlib.machinery import SourceFileLoader
    return SourceFileLoader(name, fn).load_module()


# 将 os.fspath 函数赋值给变量 os_fspath,以便更方便地引用该函数
os_fspath = os.fspath
# 将 os.PathLike 类型赋值给变量 os_PathLike,以便更方便地引用该类型
os_PathLike = os.PathLike

.\numpy\numpy\compat\tests\__init__.py

# 定义一个名为find_duplicate的函数,接收一个参数nums,该参数是一个整数列表
def find_duplicate(nums):
    # 创建一个空集合dup_set,用于存储出现过的数字
    dup_set = set()
    
    # 遍历nums列表中的每个元素num
    for num in nums:
        # 如果num已经在dup_set中存在,表示num是重复出现的数字
        if num in dup_set:
            # 返回找到的重复数字num
            return num
        # 将num加入dup_set中,记录已经出现的数字
        dup_set.add(num)
    
    # 如果没有找到重复数字,返回None
    return None

.\numpy\numpy\compat\__init__.py

"""
python
"""
兼容性模块。

此模块包含从 Python 本身或第三方扩展复制的重复代码,可能包含以下原因:

  * 兼容性
  * 我们可能只需要复制库/模块的一小部分

此模块自 1.26.0 版本起已被弃用,并将在将来的版本中移除。

"""

# 导入警告模块
import warnings
# 从内部工具模块导入 _inspect 模块
from .._utils import _inspect
# 从内部工具模块的 _inspect 模块导入 getargspec 和 formatargspec 函数
from .._utils._inspect import getargspec, formatargspec
# 从 . 模块导入 py3k 模块
from . import py3k
# 从 .py3k 模块导入所有内容
from .py3k import *

# 引发警告,指示 np.compat 在 Python 2 到 3 的转换期间使用,自 1.26.0 版本起已弃用,并将被移除
warnings.warn(
    "`np.compat`, which was used during the Python 2 to 3 transition,"
    " is deprecated since 1.26.0, and will be removed",
    DeprecationWarning, stacklevel=2
)

# 将空列表tion,"
    " is deprecated since 1.26.0, and will be removed",
    DeprecationWarning, stacklevel=2
)

# 初始化模块的公开接口列表
__all__ = []

# 将 _inspect 模块中定义的所有公开名称添加到 __all__ 中
__all__.extend(_inspect.__all__)

# 将 py3k 模块中定义的所有公开名称添加到 __all__ 中
__all__.extend(py3k.__all__)

.\numpy\numpy\conftest.py

"""
Pytest configuration and fixtures for the Numpy test suite.
"""
# 导入必要的库和模块
import os  # 导入操作系统接口
import tempfile  # 导入临时文件和目录创建的模块
from contextlib import contextmanager  # 导入上下文管理器
import warnings  # 导入警告模块

import hypothesis  # 导入假设测试库
import pytest  # 导入pytest测试框架
import numpy  # 导入NumPy库

from numpy._core._multiarray_tests import get_fpu_mode  # 导入获取FPU模式的函数

# 尝试导入scipy_doctest.conftest模块,标记是否成功导入
try:
    from scipy_doctest.conftest import dt_config
    HAVE_SCPDT = True
except ModuleNotFoundError:
    HAVE_SCPDT = False

# 初始化旧的FPU模式和结果收集字典
_old_fpu_mode = None
_collect_results = {}

# 设置hypothesis缓存的主目录,使用已知且持久的临时目录
hypothesis.configuration.set_hypothesis_home_dir(
    os.path.join(tempfile.gettempdir(), ".hypothesis")
)

# 注册两个自定义的Hypothesis配置文件,用于NumPy测试
hypothesis.settings.register_profile(
    name="numpy-profile", deadline=None, print_blob=True,
)
hypothesis.settings.register_profile(
    name="np.test() profile",
    deadline=None, print_blob=True, database=None, derandomize=True,
    suppress_health_check=list(hypothesis.HealthCheck),
)

# 根据pytest.ini文件的存在与否加载默认的Hypothesis配置文件
_pytest_ini = os.path.join(os.path.dirname(__file__), "..", "pytest.ini")
hypothesis.settings.load_profile(
    "numpy-profile" if os.path.isfile(_pytest_ini) else "np.test() profile"
)

# 设置NUMPY_EXPERIMENTAL_DTYPE_API环境变量为1,用于_umath_tests
os.environ["NUMPY_EXPERIMENTAL_DTYPE_API"] = "1"

# 定义pytest的配置函数,添加自定义标记
def pytest_configure(config):
    config.addinivalue_line("markers",
        "valgrind_error: Tests that are known to error under valgrind.")
    config.addinivalue_line("markers",
        "leaks_references: Tests that are known to leak references.")
    config.addinivalue_line("markers",
        "slow: Tests that are very slow.")
    config.addinivalue_line("markers",
        "slow_pypy: Tests that are very slow on pypy.")

# 定义pytest的命令行选项,用于设置可用内存量
def pytest_addoption(parser):
    parser.addoption("--available-memory", action="store", default=None,
                     help=("Set amount of memory available for running the "
                           "test suite. This can result to tests requiring "
                           "especially large amounts of memory to be skipped. "
                           "Equivalent to setting environment variable "
                           "NPY_AVAILABLE_MEM. Default: determined"
                           "automatically."))

# 在测试会话开始时,根据命令行选项设置环境变量NPY_AVAILABLE_MEM
def pytest_sessionstart(session):
    available_mem = session.config.getoption('available_memory')
    if available_mem is not None:
        os.environ['NPY_AVAILABLE_MEM'] = available_mem

# TODO: 移除yield测试后修复此函数
@pytest.hookimpl()
def pytest_itemcollected(item):
    """
    Check FPU precision mode was not changed during test collection.
    """
    The clumsy way we do it here is mainly necessary because numpy
    still uses yield tests, which can execute code at test collection
    time.
    """
    # 声明全局变量 _old_fpu_mode,用于存储旧的浮点数处理单元模式
    global _old_fpu_mode

    # 获取当前的浮点数处理单元模式
    mode = get_fpu_mode()

    # 如果 _old_fpu_mode 还未设置,则将当前模式赋给它
    if _old_fpu_mode is None:
        _old_fpu_mode = mode
    # 否则,如果当前模式与旧模式不同,则记录结果到 _collect_results 字典中,并更新 _old_fpu_mode
    elif mode != _old_fpu_mode:
        _collect_results[item] = (_old_fpu_mode, mode)
        _old_fpu_mode = mode
# 如果 HAVE_SCPDT 可用,则定义一个上下文管理器 warnings_errors_and_rng
if HAVE_SCPDT:
    @contextmanager
    def warnings_errors_and_rng(test=None):
        """Filter out the wall of DeprecationWarnings.
        """
        # 定义需要忽略的 DeprecationWarning 的消息列表
        msgs = ["The numpy.linalg.linalg",
                "The numpy.fft.helper",
                "dep_util",
                "pkg_resources",
                "numpy.core.umath",
                "msvccompiler",
                "Deprecated call",
                "numpy.core",
                "`np.compat`",
                "Importing from numpy.matlib",
                "This function is deprecated.",    # random_integers
                "Data type alias 'a'",     # numpy.rec.fromfile
                "Arrays of 2-dimensional vectors",   # matlib.cross
                "`in1d` is deprecated", ]
        msg = "|".join(msgs)

        # 定义需要忽略的 RuntimeWarning 的消息列表
        msgs_r = [
            "invalid value encountered",
            "divide by zero encountered"
        ]
        msg_r = "|".join(msgs_r)

        # 忽略特定类型的警告消息
        with warnings.catch_warnings():
            warnings.filterwarnings(
                'ignore', category=DeprecationWarning, message=msg
            )
            warnings.filterwarnings(
                'ignore', category=RuntimeWarning, message=msg_r
            )
            yield

    # 将定义好的上下文管理器应用于用户配置的上下文管理器
    dt_config.user_context_mgr = warnings_errors_and_rng

    # 为 doctests 添加特定于 numpy 的标记以处理未初始化情况
    dt_config.rndm_markers.add('#uninitialized')
    dt_config.rndm_markers.add('# uninitialized')

    # 导入 doctest 模块,用于查找和检查此上下文管理器下的文档测试
    import doctest
    # 设置 doctest 的选项标志,用于规范化空白和省略号处理
    dt_config.optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS

    # 将 'StringDType' 识别为 numpy.dtypes.StringDType 的命名空间检查
    dt_config.check_namespace['StringDType'] = numpy.dtypes.StringDType

    # 设置临时跳过列表,避免在 doctest 中处理以下函数
    dt_config.skiplist = set([
        'numpy.savez',    # 文件未关闭
        'numpy.matlib.savez',
        'numpy.__array_namespace_info__',
        'numpy.matlib.__array_namespace_info__',
    ])

    # 标记无法通过测试的教程文件为 xfail(预期失败),附加信息为空字符串
    dt_config.pytest_extra_xfail = {
        'how-to-verify-bug.rst': '',
        'c-info.ufunc-tutorial.rst': '',
        'basics.interoperability.rst': 'needs pandas',  # 需要 pandas
        'basics.dispatch.rst': 'errors out in /testing/overrides.py',  # 在 /testing/overrides.py 中出错
        'basics.subclassing.rst': '.. testcode:: admonitions not understood'  # 不理解警告
    }

    # 设置额外的忽略列表,用于不希望进行 doctest 集合的内容(例如可选内容)
    dt_config.pytest_extra_ignore = [
        'numpy/distutils',
        'numpy/_core/cversions.py',
        'numpy/_pyinstaller',
        'numpy/random/_examples',
        'numpy/compat',
        'numpy/f2py/_backends/_distutils.py',
    ]

.\numpy\numpy\core\arrayprint.py

# 定义一个特殊方法 __getattr__,用于在对象中获取指定属性的值
def __getattr__(attr_name):
    # 从 numpy._core.arrayprint 模块中导入 arrayprint 函数
    from numpy._core import arrayprint
    # 从 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试从 arrayprint 模块中获取指定名称的属性值
    ret = getattr(arrayprint, attr_name, None)
    # 如果获取的属性值为 None,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.arrayprint' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,提醒获取到的属性名称和其所在模块
    _raise_warning(attr_name, "arrayprint")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\defchararray.py

# 定义一个特殊方法 __getattr__,用于在获取不存在的属性时进行处理
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 defchararray 对象
    from numpy._core import defchararray
    # 从 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 defchararray 对象中的属性 attr_name
    ret = getattr(defchararray, attr_name, None)
    # 如果获取不到该属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.defchararray' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,向用户发出警告信息
    _raise_warning(attr_name, "defchararray")
    # 返回获取到的属性或方法对象
    return ret

.\numpy\numpy\core\einsumfunc.py

# 定义一个特殊的属性获取方法,用于获取指定名称的属性值
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 einsumfunc 函数或属性
    from numpy._core import einsumfunc
    # 从 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 einsumfunc 模块中指定名称的属性值
    ret = getattr(einsumfunc, attr_name, None)
    # 如果未找到指定属性,抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.einsumfunc' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,发出警告,提醒 einsumfunc 模块中的属性被访问
    _raise_warning(attr_name, "einsumfunc")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\fromnumeric.py

# 定义一个特殊的方法,用于动态获取属性值
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 fromnumeric 对象
    from numpy._core import fromnumeric
    # 从当前模块的 _utils 导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 fromnumeric 对象的属性 attr_name
    ret = getattr(fromnumeric, attr_name, None)
    # 如果未找到对应属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.fromnumeric' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,发出警告信息
    _raise_warning(attr_name, "fromnumeric")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\function_base.py

# 定义一个函数 __getattr__,用于获取指定属性名的属性值
def __getattr__(attr_name):
    # 从 numpy._core 中导入 function_base 模块
    from numpy._core import function_base
    # 从 ._utils 模块导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 获取 function_base 模块中名称为 attr_name 的属性值,如果不存在则返回 None
    ret = getattr(function_base, attr_name, None)
    # 如果未找到指定的属性值,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.function_base' has no attribute {attr_name}")
    # 发出警告,说明找到的属性值来自 function_base 模块
    _raise_warning(attr_name, "function_base")
    # 返回找到的属性值
    return ret

.\numpy\numpy\core\getlimits.py

# 定义一个特殊的属性访问方法,用于动态获取属性值
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 getlimits 函数
    from numpy._core import getlimits
    # 从当前模块的 _utils 导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 getlimits 模块中名为 attr_name 的属性值
    ret = getattr(getlimits, attr_name, None)
    # 如果获取的属性值为 None,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.getlimits' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,发出警告
    _raise_warning(attr_name, "getlimits")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\multiarray.py

# 从 numpy._core 模块中导入 multiarray 对象
from numpy._core import multiarray

# 将 "multiarray" 模块中的 "_reconstruct" 和 "scalar" 属性复制给全局命名空间,
# 以支持旧的 pickle 文件
for item in ["_reconstruct", "scalar"]:
    globals()[item] = getattr(multiarray, item)

# Pybind11(在版本 <= 2.11.1 中)从 multiarray 子模块导入 _ARRAY_API 作为 NumPy 初始化的一部分,
# 因此它必须可以无警告导入。
_ARRAY_API = multiarray._ARRAY_API

# 定义 __getattr__ 函数,用于动态获取属性
def __getattr__(attr_name):
    # 重新导入 multiarray 对象,用于获取特定属性
    from numpy._core import multiarray
    # 导入 _raise_warning 函数,用于抛出警告
    from ._utils import _raise_warning
    # 尝试从 multiarray 中获取指定属性
    ret = getattr(multiarray, attr_name, None)
    # 如果获取失败,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.multiarray' has no attribute {attr_name}")
    # 发出警告,说明属性来自 multiarray
    _raise_warning(attr_name, "multiarray")
    return ret

# 删除已导入的 multiarray 对象的引用,清理命名空间
del multiarray

.\numpy\numpy\core\numeric.py

# 定义一个特殊方法 __getattr__,用于在当前作用域中动态获取属性
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 numeric 对象
    from numpy._core import numeric
    # 从当前模块中导入 _raise_warning 函数
    from ._utils import _raise_warning

    # 定义一个特殊的对象 sentinel,用于标记属性是否存在
    sentinel = object()
    # 尝试从 numeric 对象中获取指定名称的属性,如果属性不存在,则使用 sentinel 标记
    ret = getattr(numeric, attr_name, sentinel)
    # 如果 ret 是 sentinel,则表示属性不存在,抛出 AttributeError 异常
    if ret is sentinel:
        raise AttributeError(
            f"module 'numpy.core.numeric' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,向用户发出警告,说明属性从 numeric 模块中获取
    _raise_warning(attr_name, "numeric")
    # 返回获取到的属性对象
    return ret

.\numpy\numpy\core\numerictypes.py

# 定义一个特殊方法 __getattr__,用于在属性未找到时执行
def __getattr__(attr_name):
    # 从 numpy._core 模块导入 numerictypes 对象
    from numpy._core import numerictypes
    # 从 ._utils 模块导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 numerictypes 模块中的属性 attr_name
    ret = getattr(numerictypes, attr_name, None)
    # 如果未找到该属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.numerictypes' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,传递 attr_name 和 "numerictypes" 作为参数
    _raise_warning(attr_name, "numerictypes")
    # 返回获取到的属性 ret
    return ret

.\numpy\numpy\core\overrides.py

# 定义一个特殊方法 __getattr__,用于动态获取属性的值
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 overrides 函数
    from numpy._core import overrides
    # 从当前模块的 _utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 获取 overrides 模块中名为 attr_name 的属性
    ret = getattr(overrides, attr_name, None)
    # 如果未找到对应属性,抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.overrides' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,生成警告信息
    _raise_warning(attr_name, "overrides")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\records.py

# 定义一个特殊的方法,用于动态获取对象的属性
def __getattr__(attr_name):
    # 从 numpy._core.records 模块中导入 records 对象
    from numpy._core import records
    # 从当前模块的 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 records 对象中名为 attr_name 的属性
    ret = getattr(records, attr_name, None)
    # 如果未找到指定属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.records' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,发出警告,说明属性来自 records 模块
    _raise_warning(attr_name, "records")
    # 返回获取到的属性对象
    return ret

.\numpy\numpy\core\shape_base.py

# 定义一个特殊方法 __getattr__,用于在访问对象的属性失败时自定义处理
def __getattr__(attr_name):
    # 从 numpy._core 模块导入 shape_base 对象
    from numpy._core import shape_base
    # 从当前模块的 _utils 模块导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 shape_base 对象中的属性 attr_name
    ret = getattr(shape_base, attr_name, None)
    # 如果未找到对应属性,抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.shape_base' has no attribute {attr_name}")
    # 发出警告,说明属性 attr_name 未直接在 shape_base 中找到
    _raise_warning(attr_name, "shape_base")
    # 返回找到的属性对象
    return ret

.\numpy\numpy\core\umath.py

# 定义一个特殊方法 __getattr__,用于在对象中动态获取属性
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 umath 对象
    from numpy._core import umath
    # 从当前模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 umath 对象中名为 attr_name 的属性,如果不存在则返回 None
    ret = getattr(umath, attr_name, None)
    # 如果未找到指定的属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core.umath' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,警告 umath 模块中已获取属性
    _raise_warning(attr_name, "umath")
    # 返回获取到的属性
    return ret

.\numpy\numpy\core\_dtype.py

# 定义一个特殊方法 __getattr__,用于在对象没有指定属性时进行处理
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 _dtype 对象
    from numpy._core import _dtype
    # 从 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 _dtype 对象的属性 attr_name
    ret = getattr(_dtype, attr_name, None)
    # 如果未找到指定属性,则引发 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core._dtype' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,向用户发出警告,说明属性被访问
    _raise_warning(attr_name, "_dtype")
    # 返回获取到的属性值
    return ret

.\numpy\numpy\core\_dtype_ctypes.py

# 定义一个特殊的函数 __getattr__,用于在对象中获取指定属性的方法
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 _dtype_ctypes 对象
    from numpy._core import _dtype_ctypes
    # 从 ._utils 模块中导入 _raise_warning 函数
    from ._utils import _raise_warning
    # 尝试获取 _dtype_ctypes 对象中名为 attr_name 的属性
    ret = getattr(_dtype_ctypes, attr_name, None)
    # 如果未找到指定属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core._dtype_ctypes' has no attribute {attr_name}")
    # 调用 _raise_warning 函数,提醒用户该属性来自 _dtype_ctypes 对象
    _raise_warning(attr_name, "_dtype_ctypes")
    # 返回获取到的属性
    return ret

.\numpy\numpy\core\_internal.py

# 从 numpy._core._internal 模块导入 _reconstruct 函数
# 该函数用于从 pickle 数据中重建 ndarray 数组对象
# 注意:numpy.core._internal._reconstruct 函数名称在 NumPy 1.0 之前的版本中用于 ndarray 的 pickle 数据,
# 因此不能在此处删除名称,否则会破坏向后兼容性。
def _reconstruct(subtype, shape, dtype):
    # 导入 ndarray 类型并使用其 __new__ 方法创建新的数组对象
    from numpy import ndarray
    return ndarray.__new__(subtype, shape, dtype)


# Pybind11(版本 <= 2.11.1)从 _internal 子模块导入 _dtype_from_pep3118 函数,
# 因此必须能够无警告地导入它。
_dtype_from_pep3118 = _internal._dtype_from_pep3118

# 定义一个 __getattr__ 函数,用于在运行时动态获取属性
def __getattr__(attr_name):
    # 导入 numpy._core._internal 模块
    from numpy._core import _internal
    # 导入自定义工具函数 _raise_warning
    from ._utils import _raise_warning
    # 尝试从 _internal 模块获取指定名称的属性
    ret = getattr(_internal, attr_name, None)
    # 如果未找到指定名称的属性,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            f"module 'numpy.core._internal' has no attribute {attr_name}")
    # 发出警告,说明此属性来自 _internal 模块
    _raise_warning(attr_name, "_internal")
    return ret

.\numpy\numpy\core\_multiarray_umath.py

# 从 numpy._core 模块中导入 _multiarray_umath 对象
from numpy._core import _multiarray_umath
# 从 numpy 模块中导入 ufunc 类型
from numpy import ufunc

# 遍历 _multiarray_umath 对象的所有属性名称
for item in _multiarray_umath.__dir__():
    # 对于每个属性名称,获取其对应的属性对象
    attr = getattr(_multiarray_umath, item)
    # 如果该属性对象属于 ufunc 类型
    if isinstance(attr, ufunc):
        # 将该属性对象添加到全局命名空间中,属性名称和对象相同
        globals()[item] = attr


# 定义一个特殊的 __getattr__ 函数
def __getattr__(attr_name):
    # 从 numpy._core 模块中导入 _multiarray_umath 对象
    from numpy._core import _multiarray_umath
    # 从当前模块的 ._utils 子模块中导入 _raise_warning 函数

    # 如果 attr_name 是 "_ARRAY_API" 或 "_UFUNC_API"
    if attr_name in {"_ARRAY_API", "_UFUNC_API"}:
        # 从 numpy.version 模块中导入 short_version 变量
        from numpy.version import short_version
        # 导入 textwrap 模块,用于格式化消息文本
        import textwrap
        # 导入 traceback 模块,用于生成调用堆栈信息
        import traceback
        # 导入 sys 模块,用于访问标准错误流
        import sys

        # 创建一条包含详细信息的消息字符串
        msg = textwrap.dedent(f"""
            A module that was compiled using NumPy 1.x cannot be run in
            NumPy {short_version} as it may crash. To support both 1.x and 2.x
            versions of NumPy, modules must be compiled with NumPy 2.0.
            Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.

            If you are a user of the module, the easiest solution will be to
            downgrade to 'numpy<2' or try to upgrade the affected module.
            We expect that some modules will need time to support NumPy 2.

            """)
        # 创建一个包含调用堆栈的消息字符串
        tb_msg = "Traceback (most recent call last):"
        for line in traceback.format_stack()[:-1]:
            if "frozen importlib" in line:
                continue
            tb_msg += line

        # 将消息和调用堆栈信息写入标准错误流
        sys.stderr.write(msg + tb_msg)
        # 抛出 ImportError 异常,包含详细消息
        raise ImportError(msg)

    # 尝试从 _multiarray_umath 对象中获取指定名称的属性对象
    ret = getattr(_multiarray_umath, attr_name, None)
    # 如果获取的属性对象为 None,则抛出 AttributeError 异常
    if ret is None:
        raise AttributeError(
            "module 'numpy.core._multiarray_umath' has no attribute "
            f"{attr_name}")
    # 调用 _raise_warning 函数,向用户发出警告
    _raise_warning(attr_name, "_multiarray_umath")
    # 返回获取到的属性对象
    return ret

# 从全局命名空间中删除 _multiarray_umath 和 ufunc 变量
del _multiarray_umath, ufunc

.\numpy\numpy\core\_utils.py

# 导入警告模块,用于生成警告信息
import warnings

# 定义一个函数,用于发出警告信息
def _raise_warning(attr: str, submodule: str = None) -> None:
    # 定义新旧模块的名称
    new_module = "numpy._core"
    old_module = "numpy.core"

    # 如果有子模块,添加到模块名称中
    if submodule is not None:
        new_module = f"{new_module}.{submodule}"
        old_module = f"{old_module}.{submodule}"

    # 发出警告,说明旧模块已弃用并重命名
    warnings.warn(
        f"{old_module} is deprecated and has been renamed to {new_module}. "
        "The numpy._core namespace contains private NumPy internals and its "
        "use is discouraged, as NumPy internals can change without warning in "
        "any release. In practice, most real-world usage of numpy.core is to "
        "access functionality in the public NumPy API. If that is the case, "
        "use the public NumPy API. If not, you are using NumPy internals. "
        "If you would still like to access an internal attribute, "
        f"use {new_module}.{attr}.",
        DeprecationWarning, 
        stacklevel=3  # 设置警告的堆栈级别
    )

.\numpy\numpy\core\__init__.py

"""
The `numpy.core` submodule exists solely for backward compatibility
purposes. The original `core` was renamed to `_core` and made private.
`numpy.core` will be removed in the future.
"""
# 从 `numpy` 包中导入 `_core` 子模块,用于向后兼容性目的
from numpy import _core

# 从当前包的 `_utils` 模块中导入 `_raise_warning` 函数
from ._utils import _raise_warning


# We used to use `np.core._ufunc_reconstruct` to unpickle.
# This is unnecessary, but old pickles saved before 1.20 will be using it,
# and there is no reason to break loading them.
# 定义 `_ufunc_reconstruct` 函数,用于反序列化时重建 ufunc 对象
def _ufunc_reconstruct(module, name):
    # 导入指定模块 `module` 并返回其中指定的 `name` 对象
    # `fromlist` 参数确保当模块名嵌套时,`mod` 指向最内层模块而非父包
    mod = __import__(module, fromlist=[name])
    return getattr(mod, name)


# force lazy-loading of submodules to ensure a warning is printed

# 定义 `__all__` 列表,包含公开的子模块名称,用于 `from package import *` 语法
__all__ = ["arrayprint", "defchararray", "_dtype_ctypes", "_dtype",
           "einsumfunc", "fromnumeric", "function_base", "getlimits",
           "_internal", "multiarray", "_multiarray_umath", "numeric",
           "numerictypes", "overrides", "records", "shape_base", "umath"]

# 定义 `__getattr__` 函数,用于动态获取 `numpy.core` 中的属性
def __getattr__(attr_name):
    # 从 `numpy._core` 中获取指定属性 `attr_name`
    attr = getattr(_core, attr_name)
    # 调用 `_raise_warning` 函数,对获取的属性进行警告处理
    _raise_warning(attr_name)
    # 返回获取的属性
    return attr

.\numpy\numpy\core\__init__.pyi

# 导入所需的模块:re 用于正则表达式操作,os 用于文件路径操作
import re
import os

# 定义函数 find_files,接收文件路径和正则表达式作为参数
def find_files(dir, regex):
    # 初始化一个空列表,用于存储符合条件的文件路径
    files = []
    # 遍历指定目录及其子目录下的所有文件和文件夹
    for root, dirs, filenames in os.walk(dir):
        # 对每个文件名进行正则匹配
        for filename in filenames:
            # 如果文件名符合正则表达式条件
            if re.match(regex, filename):
                # 构建文件的完整路径并添加到列表中
                files.append(os.path.join(root, filename))
    # 返回符合条件的文件路径列表
    return files

.\numpy\numpy\ctypeslib.py

"""
============================
``ctypes`` Utility Functions
============================

See Also
--------
load_library : Load a C library.
ndpointer : Array restype/argtype with verification.
as_ctypes : Create a ctypes array from an ndarray.
as_array : Create an ndarray from a ctypes array.

References
----------
.. [1] "SciPy Cookbook: ctypes", https://scipy-cookbook.readthedocs.io/items/Ctypes.html

Examples
--------
Load the C library:

>>> _lib = np.ctypeslib.load_library('libmystuff', '.')     #doctest: +SKIP

Our result type, an ndarray that must be of type double, be 1-dimensional
and is C-contiguous in memory:

>>> array_1d_double = np.ctypeslib.ndpointer(
...                          dtype=np.double,
...                          ndim=1, flags='CONTIGUOUS')    #doctest: +SKIP

Our C-function typically takes an array and updates its values
in-place.  For example::

    void foo_func(double* x, int length)
    {
        int i;
        for (i = 0; i < length; i++) {
            x[i] = i*i;
        }
    }

We wrap it using:

>>> _lib.foo_func.restype = None                      #doctest: +SKIP
>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP

Then, we're ready to call ``foo_func``:

>>> out = np.empty(15, dtype=np.double)
>>> _lib.foo_func(out, len(out))                #doctest: +SKIP

"""
__all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array',
           'as_ctypes_type']

import os                                       # 导入操作系统接口模块
from numpy import (                             # 从 numpy 库导入以下模块:
    integer, ndarray, dtype as _dtype, asarray, frombuffer
)
from numpy._core.multiarray import _flagdict, flagsobj  # 导入 numpy 的内部多维数组相关模块

try:
    import ctypes                               # 尝试导入 ctypes 库
except ImportError:
    ctypes = None

if ctypes is None:                              # 如果 ctypes 库不可用,定义一个 _dummy 函数来抛出 ImportError
    def _dummy(*args, **kwds):
        """
        Dummy object that raises an ImportError if ctypes is not available.

        Raises
        ------
        ImportError
            If ctypes is not available.

        """
        raise ImportError("ctypes is not available.")
    load_library = _dummy                        # 定义 load_library, as_ctypes, as_array 为 _dummy 函数
    as_ctypes = _dummy
    as_array = _dummy
    from numpy import intp as c_intp            # 从 numpy 导入 intp 并命名为 c_intp
    _ndptr_base = object                        # _ndptr_base 设为 Python 对象
else:
    import numpy._core._internal as nic          # 导入 numpy 内部的 _internal 模块并命名为 nic
    c_intp = nic._getintp_ctype()               # 获取 ctypes 中的 c_intp 类型
    del nic                                     # 删除 nic 引用,释放内存
    _ndptr_base = ctypes.c_void_p               # 设置 _ndptr_base 为 ctypes 的 c_void_p 类型

    # Adapted from Albert Strasheim
    def load_library(libname, loader_path):
        """
        It is possible to load a library using

        >>> lib = ctypes.cdll[<full_path_name>] # doctest: +SKIP

        But there are cross-platform considerations, such as library file extensions,
        plus the fact Windows will just load the first library it finds with that name.
        NumPy supplies the load_library function as a convenience.

        .. versionchanged:: 1.20.0
            Allow libname and loader_path to take any
            :term:`python:path-like object`.

        Parameters
        ----------
        libname : path-like
            Name of the library, which can have 'lib' as a prefix,
            but without an extension.
        loader_path : path-like
            Where the library can be found.

        Returns
        -------
        ctypes.cdll[libpath] : library object
           A ctypes library object

        Raises
        ------
        OSError
            If there is no library with the expected extension, or the
            library is defective and cannot be loaded.
        """
        # Convert path-like objects into strings
        libname = os.fsdecode(libname)  # 解码并获取库名称的字符串表示
        loader_path = os.fsdecode(loader_path)  # 解码并获取加载路径的字符串表示

        ext = os.path.splitext(libname)[1]  # 获取库名称的文件扩展名
        if not ext:
            import sys
            import sysconfig
            # 尝试使用平台特定的库文件名加载库,否则默认为libname.[so|dll|dylib]。
            # 有时这些文件在非Linux平台上会构建错误。
            base_ext = ".so"
            if sys.platform.startswith("darwin"):
                base_ext = ".dylib"
            elif sys.platform.startswith("win"):
                base_ext = ".dll"
            libname_ext = [libname + base_ext]
            so_ext = sysconfig.get_config_var("EXT_SUFFIX")
            if not so_ext == base_ext:
                libname_ext.insert(0, libname + so_ext)
        else:
            libname_ext = [libname]

        loader_path = os.path.abspath(loader_path)  # 获取加载路径的绝对路径
        if not os.path.isdir(loader_path):
            libdir = os.path.dirname(loader_path)  # 获取加载路径的父目录
        else:
            libdir = loader_path

        for ln in libname_ext:
            libpath = os.path.join(libdir, ln)  # 组合库文件的完整路径
            if os.path.exists(libpath):  # 检查库文件是否存在
                try:
                    return ctypes.cdll[libpath]  # 尝试加载库文件并返回 ctypes 库对象
                except OSError:
                    ## defective lib file
                    raise  # 抛出异常,说明库文件有问题
        ## if no successful return in the libname_ext loop:
        raise OSError("no file with expected extension")  # 如果在 libname_ext 循环中没有成功返回,则抛出异常
def _num_fromflags(flaglist):
    # 初始化一个计数器
    num = 0
    # 遍历传入的标志列表,将每个标志对应的值累加到计数器中
    for val in flaglist:
        num += _flagdict[val]
    # 返回累加后的结果作为标志的数字表示
    return num

_flagnames = ['C_CONTIGUOUS', 'F_CONTIGUOUS', 'ALIGNED', 'WRITEABLE',
              'OWNDATA', 'WRITEBACKIFCOPY']
def _flags_fromnum(num):
    # 初始化一个空列表用来存储结果
    res = []
    # 遍历已定义的所有标志名称
    for key in _flagnames:
        # 获取当前标志对应的数值
        value = _flagdict[key]
        # 检查当前标志是否在给定的数字表示中
        if (num & value):
            # 如果在其中,则将该标志名称添加到结果列表中
            res.append(key)
    # 返回所有匹配的标志名称列表
    return res


class _ndptr(_ndptr_base):
    @classmethod
    def from_param(cls, obj):
        # 检查传入的对象是否为 ndarray 类型
        if not isinstance(obj, ndarray):
            raise TypeError("argument must be an ndarray")
        # 如果定义了特定的数据类型,检查传入数组是否符合要求
        if cls._dtype_ is not None \
               and obj.dtype != cls._dtype_:
            raise TypeError("array must have data type %s" % cls._dtype_)
        # 如果定义了特定的维度数,检查传入数组是否符合要求
        if cls._ndim_ is not None \
               and obj.ndim != cls._ndim_:
            raise TypeError("array must have %d dimension(s)" % cls._ndim_)
        # 如果定义了特定的形状,检查传入数组是否符合要求
        if cls._shape_ is not None \
               and obj.shape != cls._shape_:
            raise TypeError("array must have shape %s" % str(cls._shape_))
        # 如果定义了特定的标志,检查传入数组是否符合要求
        if cls._flags_ is not None \
               and ((obj.flags.num & cls._flags_) != cls._flags_):
            raise TypeError("array must have flags %s" %
                    _flags_fromnum(cls._flags_))
        # 返回传入数组的 ctypes 对象
        return obj.ctypes


class _concrete_ndptr(_ndptr):
    """
    Like _ndptr, but with `_shape_` and `_dtype_` specified.

    Notably, this means the pointer has enough information to reconstruct
    the array, which is not generally true.
    """
    def _check_retval_(self):
        """
        This method is called when this class is used as the .restype
        attribute for a shared-library function, to automatically wrap the
        pointer into an array.
        """
        # 返回指针指向的数据作为 ndarray 对象
        return self.contents

    @property
    def contents(self):
        """
        Get an ndarray viewing the data pointed to by this pointer.

        This mirrors the `contents` attribute of a normal ctypes pointer
        """
        # 构建完整的数据类型描述
        full_dtype = _dtype((self._dtype_, self._shape_))
        # 根据完整的数据类型描述创建对应的 ctypes 类型
        full_ctype = ctypes.c_char * full_dtype.itemsize
        # 将当前指针对象转换为指向完整 ctypes 类型的指针,并获取其内容
        buffer = ctypes.cast(self, ctypes.POINTER(full_ctype)).contents
        # 将 ctypes 缓冲区转换为 ndarray,并去掉多余的维度
        return frombuffer(buffer, dtype=full_dtype).squeeze(axis=0)


# Factory for an array-checking class with from_param defined for
#  use with ctypes argtypes mechanism
_pointer_type_cache = {}
def ndpointer(dtype=None, ndim=None, shape=None, flags=None):
    """
    Array-checking restype/argtypes.

    An ndpointer instance is used to describe an ndarray in restypes
    and argtypes specifications.  This approach is more flexible than
    using, for example, ``POINTER(c_double)``, since several restrictions
    can be specified, which are verified upon calling the ctypes function.
    These include data type, number of dimensions, shape and flags.  If a
    given array does not satisfy the specified restrictions,
    a ``TypeError`` is raised.

    Parameters
    ----------
    """
    # 此函数主要用于创建一个描述 ndarray 的类型,检查其数据类型、维度、形状和标志
    pass
    # data-type 数据类型,可选参数
    dtype : data-type, optional
    # int 整数,可选参数
    ndim : int, optional
    # tuple of ints 整数元组,可选参数
    shape : tuple of ints, optional
    # str or tuple of str 字符串或字符串元组,数组标志;可以是以下一项或多项:
    # C_CONTIGUOUS / C / CONTIGUOUS
    # F_CONTIGUOUS / F / FORTRAN
    # OWNDATA / O
    # WRITEABLE / W
    # ALIGNED / A
    # WRITEBACKIFCOPY / X

    # 返回
    -------
    # ndpointer 类型对象
    klass : ndpointer type object
    # 类型对象,是一个包含 dtype、ndim、shape 和 flags 信息的 `_ndtpr` 实例。

    # 异常
    ------
    # TypeError
    # 如果给定的数组不满足指定的限制条件。

    # 示例
    --------
    # 将 clib.somefunc 的 argtypes 设置为 [np.ctypeslib.ndpointer(dtype=np.float64,
    #                                                  ndim=1,
    #                                                  flags='C_CONTIGUOUS')]
    ... #doctest: +SKIP
    # 调用 clib.somefunc,传入 np.array([1, 2, 3], dtype=np.float64) 作为参数
    ... #doctest: +SKIP
    """

    # 将 dtype 标准化为 Optional[dtype]
    if dtype is not None:
        dtype = _dtype(dtype)

    # 将 flags 标准化为 Optional[int]
    num = None
    if flags is not None:
        if isinstance(flags, str):
            flags = flags.split(',')
        elif isinstance(flags, (int, integer)):
            num = flags
            flags = _flags_fromnum(num)
        elif isinstance(flags, flagsobj):
            num = flags.num
            flags = _flags_fromnum(num)
        if num is None:
            try:
                flags = [x.strip().upper() for x in flags]
            except Exception as e:
                raise TypeError("invalid flags specification") from e
            num = _num_fromflags(flags)

    # 将 shape 标准化为 Optional[tuple]
    if shape is not None:
        try:
            shape = tuple(shape)
        except TypeError:
            # 单个整数 -> 转为 1 元组
            shape = (shape,)

    # 缓存键,包含 dtype、ndim、shape 和 num
    cache_key = (dtype, ndim, shape, num)

    try:
        # 尝试从缓存中获取 _pointer_type_cache 中的值
        return _pointer_type_cache[cache_key]
    except KeyError:
        pass

    # 为新类型生成一个名称
    if dtype is None:
        name = 'any'
    elif dtype.names is not None:
        name = str(id(dtype))
    else:
        name = dtype.str
    if ndim is not None:
        name += "_%dd" % ndim
    if shape is not None:
        name += "_"+"x".join(str(x) for x in shape)
    if flags is not None:
        name += "_"+"_".join(flags)

    # 如果 dtype 和 shape 都不为 None,则基于 _concrete_ndptr
    # 否则基于 _ndptr
    if dtype is not None and shape is not None:
        base = _concrete_ndptr
    else:
        base = _ndptr

    # 创建一个新类型 klass,类型名为 'ndpointer_%s' % name
    klass = type("ndpointer_%s"%name, (base,),
                 {"_dtype_": dtype,
                  "_shape_" : shape,
                  "_ndim_" : ndim,
                  "_flags_" : num})
    # 将 klass 存储到 _pointer_type_cache 中,使用 cache_key 作为键
    _pointer_type_cache[cache_key] = klass
    return klass
if ctypes is not None:
    # 定义函数 _ctype_ndarray,用于创建给定元素类型和形状的 ndarray
    def _ctype_ndarray(element_type, shape):
        """ Create an ndarray of the given element type and shape """
        # 反向遍历形状,逐步构建元素类型
        for dim in shape[::-1]:
            element_type = dim * element_type
            # 防止类型名称包含 np.ctypeslib
            element_type.__module__ = None
        return element_type


    # 定义函数 _get_scalar_type_map,返回将本机字节序标量 dtype 映射到 ctypes 类型的字典
    def _get_scalar_type_map():
        """
        Return a dictionary mapping native endian scalar dtype to ctypes types
        """
        ct = ctypes
        # 定义简单的 ctypes 类型列表
        simple_types = [
            ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong,
            ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong,
            ct.c_float, ct.c_double,
            ct.c_bool,
        ]
        # 返回字典,映射 dtype 到对应的 ctypes 类型
        return {_dtype(ctype): ctype for ctype in simple_types}


    # 获取本机字节序标量 dtype 到 ctypes 类型的映射
    _scalar_type_map = _get_scalar_type_map()


    # 定义函数 _ctype_from_dtype_scalar,根据 dtype 返回对应的 ctypes 类型
    def _ctype_from_dtype_scalar(dtype):
        # 确保将 `=` 转换为本机字节序的 <, >, 或 |
        dtype_with_endian = dtype.newbyteorder('S').newbyteorder('S')
        dtype_native = dtype.newbyteorder('=')
        try:
            # 根据本机字节序的 dtype 获取对应的 ctypes 类型
            ctype = _scalar_type_map[dtype_native]
        except KeyError as e:
            # 抛出异常,表示无法转换该 dtype 到 ctypes 类型
            raise NotImplementedError(
                "Converting {!r} to a ctypes type".format(dtype)
            ) from None

        # 根据 dtype 的字节序调整 ctypes 类型
        if dtype_with_endian.byteorder == '>':
            ctype = ctype.__ctype_be__
        elif dtype_with_endian.byteorder == '<':
            ctype = ctype.__ctype_le__

        return ctype


    # 定义函数 _ctype_from_dtype_subarray,根据 dtype 的子数组返回对应的 ctypes 类型
    def _ctype_from_dtype_subarray(dtype):
        # 获取元素 dtype 和形状
        element_dtype, shape = dtype.subdtype
        # 根据元素 dtype 获取对应的 ctypes 类型
        ctype = _ctype_from_dtype(element_dtype)
        # 使用 _ctype_ndarray 创建 ndarray 类型,并返回
        return _ctype_ndarray(ctype, shape)
    # 根据结构化数据类型(dtype)创建对应的 ctypes 类型,支持嵌套结构和数组
    def _ctype_from_dtype_structured(dtype):
        # 提取每个字段的偏移量信息
        field_data = []
        for name in dtype.names:
            # 获取字段的数据类型和偏移量
            field_dtype, offset = dtype.fields[name][:2]
            # 将字段信息存入列表
            field_data.append((offset, name, _ctype_from_dtype(field_dtype)))
    
        # ctypes 不关心字段的顺序,按偏移量排序字段信息
        field_data = sorted(field_data, key=lambda f: f[0])
    
        # 如果有多个字段且所有字段的偏移量均为 0,则为联合体(union)
        if len(field_data) > 1 and all(offset == 0 for offset, name, ctype in field_data):
            # 初始化联合体的大小和字段列表
            size = 0
            _fields_ = []
            for offset, name, ctype in field_data:
                _fields_.append((name, ctype))
                size = max(size, ctypes.sizeof(ctype))
    
            # 如果结构体的总大小与 dtype 中定义的大小不一致,则添加填充字段
            if dtype.itemsize != size:
                _fields_.append(('', ctypes.c_char * dtype.itemsize))
    
            # 手动插入了填充字段,因此总是设置 `_pack_` 为 1
            return type('union', (ctypes.Union,), dict(
                _fields_=_fields_,
                _pack_=1,
                __module__=None,
            ))
        else:
            last_offset = 0
            _fields_ = []
            for offset, name, ctype in field_data:
                # 计算字段之间的填充空间
                padding = offset - last_offset
                if padding < 0:
                    raise NotImplementedError("Overlapping fields")
                if padding > 0:
                    _fields_.append(('', ctypes.c_char * padding))
    
                _fields_.append((name, ctype))
                last_offset = offset + ctypes.sizeof(ctype)
    
            # 计算最后一个字段之后的填充空间
            padding = dtype.itemsize - last_offset
            if padding > 0:
                _fields_.append(('', ctypes.c_char * padding))
    
            # 手动插入了填充字段,因此总是设置 `_pack_` 为 1
            return type('struct', (ctypes.Structure,), dict(
                _fields_=_fields_,
                _pack_=1,
                __module__=None,
            ))
    
    
    def _ctype_from_dtype(dtype):
        # 如果数据类型具有字段信息,则调用 _ctype_from_dtype_structured 处理
        if dtype.fields is not None:
            return _ctype_from_dtype_structured(dtype)
        # 如果数据类型具有子数据类型信息,则调用 _ctype_from_dtype_subarray 处理
        elif dtype.subdtype is not None:
            return _ctype_from_dtype_subarray(dtype)
        # 否则,将数据类型视为标量,调用 _ctype_from_dtype_scalar 处理
        else:
            return _ctype_from_dtype_scalar(dtype)
    def as_ctypes_type(dtype):
        r"""
        Convert a dtype into a ctypes type.

        Parameters
        ----------
        dtype : dtype
            The dtype to convert

        Returns
        -------
        ctype
            A ctype scalar, union, array, or struct

        Raises
        ------
        NotImplementedError
            If the conversion is not possible

        Notes
        -----
        This function does not losslessly round-trip in either direction.

        ``np.dtype(as_ctypes_type(dt))`` will:

        - insert padding fields
        - reorder fields to be sorted by offset
        - discard field titles

        ``as_ctypes_type(np.dtype(ctype))`` will:

        - discard the class names of `ctypes.Structure`\ s and
          `ctypes.Union`\ s
        - convert single-element `ctypes.Union`\ s into single-element
          `ctypes.Structure`\ s
        - insert padding fields

        """
        # 调用内部函数 _ctype_from_dtype 进行 dtype 到 ctypes 类型的转换
        return _ctype_from_dtype(_dtype(dtype))


    def as_array(obj, shape=None):
        """
        Create a numpy array from a ctypes array or POINTER.

        The numpy array shares the memory with the ctypes object.

        The shape parameter must be given if converting from a ctypes POINTER.
        The shape parameter is ignored if converting from a ctypes array
        """
        if isinstance(obj, ctypes._Pointer):
            # 如果 obj 是 ctypes._Pointer 类型,则将其转换为指定 shape 的数组
            # 如果 shape 为 None,则抛出 TypeError 异常
            if shape is None:
                raise TypeError(
                    'as_array() requires a shape argument when called on a '
                    'pointer')
            # 构造指向 obj 的指针类型 p_arr_type
            p_arr_type = ctypes.POINTER(_ctype_ndarray(obj._type_, shape))
            # 使用 ctypes.cast 将 obj 转换为 p_arr_type 指向的内容(数组)
            obj = ctypes.cast(obj, p_arr_type).contents

        # 调用 asarray 函数,返回 obj 的 numpy 数组表示
        return asarray(obj)


    def as_ctypes(obj):
        """Create and return a ctypes object from a numpy array.  Actually
        anything that exposes the __array_interface__ is accepted."""
        # 获取 obj 的 __array_interface__
        ai = obj.__array_interface__
        # 如果数组是 strided arrays,则抛出 TypeError 异常
        if ai["strides"]:
            raise TypeError("strided arrays not supported")
        # 如果 __array_interface__ 的版本不是 3,则抛出 TypeError 异常
        if ai["version"] != 3:
            raise TypeError("only __array_interface__ version 3 supported")
        # 获取数组的数据地址和 readonly 属性
        addr, readonly = ai["data"]
        # 如果数组是只读的,则抛出 TypeError 异常
        if readonly:
            raise TypeError("readonly arrays unsupported")

        # 根据 ai["typestr"] 调用 as_ctypes_type 函数转换为对应的 ctypes 标量类型
        ctype_scalar = as_ctypes_type(ai["typestr"])
        # 构造一个 ctypes 对象,类型是 _ctype_ndarray(ctype_scalar, ai["shape"])
        result_type = _ctype_ndarray(ctype_scalar, ai["shape"])
        # 使用 from_address 方法从地址 addr 创建 result_type 类型的对象 result
        result = result_type.from_address(addr)
        # 将 obj 保存在 result 的 __keep 属性中
        result.__keep = obj
        return result

.\numpy\numpy\ctypeslib.pyi

# NOTE: Numpy's mypy plugin is used for importing the correct
# platform-specific `ctypes._SimpleCData[int]` sub-type
# 导入正确的平台特定的 `ctypes._SimpleCData[int]` 子类型,使用了 Numpy 的 mypy 插件

from ctypes import c_int64 as _c_intp

import os
import ctypes
from collections.abc import Iterable, Sequence
from typing import (
    Literal as L,
    Any,
    TypeVar,
    Generic,
    overload,
    ClassVar,
)

import numpy as np
from numpy import (
    ndarray,
    dtype,
    generic,
    byte,
    short,
    intc,
    long,
    longlong,
    intp,
    ubyte,
    ushort,
    uintc,
    ulong,
    ulonglong,
    uintp,
    single,
    double,
    longdouble,
    void,
)
from numpy._core._internal import _ctypes
from numpy._core.multiarray import flagsobj
from numpy._typing import (
    # Arrays
    NDArray,
    _ArrayLike,

    # Shapes
    _ShapeLike,

    # DTypes
    DTypeLike,
    _DTypeLike,
    _VoidDTypeLike,
    _BoolCodes,
    _UByteCodes,
    _UShortCodes,
    _UIntCCodes,
    _ULongCodes,
    _ULongLongCodes,
    _ByteCodes,
    _ShortCodes,
    _IntCCodes,
    _LongCodes,
    _LongLongCodes,
    _SingleCodes,
    _DoubleCodes,
    _LongDoubleCodes,
)

# TODO: Add a proper `_Shape` bound once we've got variadic typevars
# TODO: 添加适当的 `_Shape` 约束一旦我们有了变长类型变量(PEP 646)

_DType = TypeVar("_DType", bound=dtype[Any])
_DTypeOptional = TypeVar("_DTypeOptional", bound=None | dtype[Any])
_SCT = TypeVar("_SCT", bound=generic)

_FlagsKind = L[
    'C_CONTIGUOUS', 'CONTIGUOUS', 'C',
    'F_CONTIGUOUS', 'FORTRAN', 'F',
    'ALIGNED', 'A',
    'WRITEABLE', 'W',
    'OWNDATA', 'O',
    'WRITEBACKIFCOPY', 'X',
]

# TODO: Add a shape typevar once we have variadic typevars (PEP 646)
# TODO: 一旦有了变长类型变量,添加一个形状类型变量(PEP 646)

class _ndptr(ctypes.c_void_p, Generic[_DTypeOptional]):
    # In practice these 4 classvars are defined in the dynamic class
    # returned by `ndpointer`
    # 实际上这四个类变量在由 `ndpointer` 返回的动态类中定义
    _dtype_: ClassVar[_DTypeOptional]
    _shape_: ClassVar[None]
    _ndim_: ClassVar[None | int]
    _flags_: ClassVar[None | list[_FlagsKind]]

    @overload
    @classmethod
    def from_param(cls: type[_ndptr[None]], obj: NDArray[Any]) -> _ctypes[Any]: ...
    @overload
    @classmethod
    def from_param(cls: type[_ndptr[_DType]], obj: ndarray[Any, _DType]) -> _ctypes[Any]: ...

class _concrete_ndptr(_ndptr[_DType]):
    _dtype_: ClassVar[_DType]
    _shape_: ClassVar[tuple[int, ...]]
    @property
    def contents(self) -> ndarray[Any, _DType]: ...
    # 属性方法,返回 ndarray,其元素类型为 `_DType`

def load_library(
    libname: str | bytes | os.PathLike[str] | os.PathLike[bytes],
    loader_path: str | bytes | os.PathLike[str] | os.PathLike[bytes],
) -> ctypes.CDLL:
    # 加载动态链接库,返回 ctypes.CDLL 对象
    pass

__all__: list[str]

c_intp = _c_intp

@overload
def ndpointer(
    dtype: None = ...,
    ndim: int = ...,
    shape: None | _ShapeLike = ...,
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
) -> type[_ndptr[None]]: ...
@overload
def ndpointer(
    dtype: _DTypeLike[_SCT],
    ndim: int = ...,
    *,
    shape: _ShapeLike,
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
) -> type[_concrete_ndptr[dtype[_SCT]]]: ...
@overload
def ndpointer(
    dtype: DTypeLike,
    ndim: int = ...,
    *,
    shape: _ShapeLike = ...,
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,
) -> type[_ndptr[dtype]]: ...
    # 根据指定的参数生成 ndarray 指针类型,支持多种重载形式
    pass
    ndim: int = ...,  # 定义一个类型为整数的变量 ndim,并初始化为占位符 ...
    *,  # 分隔位置参数和关键字参数的标记
    shape: _ShapeLike,  # 定义一个形状变量 shape,其类型为 _ShapeLike
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,  # 定义一个 flags 变量,其类型可以是 None、_FlagsKind 类型、_FlagsKind 的可迭代对象、整数或 flagsobj 类型,并初始化为占位符 ...
# 定义一个函数签名,用于创建特定类型的指针对象
def ndpointer(
    dtype: _DTypeLike[_SCT],    # 数据类型参数,可以是具体类型或类型的别名
    ndim: int = ...,            # 数组的维度,默认为省略值,表示维度不固定
    shape: None = ...,          # 数组的形状,默认为None,表示形状不固定
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,  # 标志参数,可以是None、单个标志、标志集合或整数
) -> type[_ndptr[dtype[_SCT]]]:  # 返回值类型为特定数据类型的指针类型

# 函数重载,支持更多的数据类型作为输入
def ndpointer(
    dtype: DTypeLike,           # 数据类型参数,可以是具体类型或类型的别名
    ndim: int = ...,            # 数组的维度,默认为省略值,表示维度不固定
    shape: None = ...,          # 数组的形状,默认为None,表示形状不固定
    flags: None | _FlagsKind | Iterable[_FlagsKind] | int | flagsobj = ...,  # 标志参数,可以是None、单个标志、标志集合或整数
) -> type[_ndptr[dtype[Any]]]:  # 返回值类型为任意数据类型的指针类型

# 函数重载,将特定的 NumPy 数据类型转换为对应的 ctypes 类型
def as_ctypes_type(dtype: _BoolCodes | _DTypeLike[np.bool] | type[ctypes.c_bool]) -> type[ctypes.c_bool]:  # 返回值类型为 ctypes.c_bool 类型

def as_ctypes_type(dtype: _ByteCodes | _DTypeLike[byte] | type[ctypes.c_byte]) -> type[ctypes.c_byte]:  # 返回值类型为 ctypes.c_byte 类型

def as_ctypes_type(dtype: _ShortCodes | _DTypeLike[short] | type[ctypes.c_short]) -> type[ctypes.c_short]:  # 返回值类型为 ctypes.c_short 类型

def as_ctypes_type(dtype: _IntCCodes | _DTypeLike[intc] | type[ctypes.c_int]) -> type[ctypes.c_int]:  # 返回值类型为 ctypes.c_int 类型

def as_ctypes_type(dtype: _LongCodes | _DTypeLike[long] | type[ctypes.c_long]) -> type[ctypes.c_long]:  # 返回值类型为 ctypes.c_long 类型

def as_ctypes_type(dtype: type[int]) -> type[c_intp]:  # 返回值类型为 c_intp 类型

def as_ctypes_type(dtype: _LongLongCodes | _DTypeLike[longlong] | type[ctypes.c_longlong]) -> type[ctypes.c_longlong]:  # 返回值类型为 ctypes.c_longlong 类型

def as_ctypes_type(dtype: _UByteCodes | _DTypeLike[ubyte] | type[ctypes.c_ubyte]) -> type[ctypes.c_ubyte]:  # 返回值类型为 ctypes.c_ubyte 类型

def as_ctypes_type(dtype: _UShortCodes | _DTypeLike[ushort] | type[ctypes.c_ushort]) -> type[ctypes.c_ushort]:  # 返回值类型为 ctypes.c_ushort 类型

def as_ctypes_type(dtype: _UIntCCodes | _DTypeLike[uintc] | type[ctypes.c_uint]) -> type[ctypes.c_uint]:  # 返回值类型为 ctypes.c_uint 类型

def as_ctypes_type(dtype: _ULongCodes | _DTypeLike[ulong] | type[ctypes.c_ulong]) -> type[ctypes.c_ulong]:  # 返回值类型为 ctypes.c_ulong 类型

def as_ctypes_type(dtype: _ULongLongCodes | _DTypeLike[ulonglong] | type[ctypes.c_ulonglong]) -> type[ctypes.c_ulonglong]:  # 返回值类型为 ctypes.c_ulonglong 类型

def as_ctypes_type(dtype: _SingleCodes | _DTypeLike[single] | type[ctypes.c_float]) -> type[ctypes.c_float]:  # 返回值类型为 ctypes.c_float 类型

def as_ctypes_type(dtype: _DoubleCodes | _DTypeLike[double] | type[float | ctypes.c_double]) -> type[ctypes.c_double]:  # 返回值类型为 ctypes.c_double 类型

def as_ctypes_type(dtype: _LongDoubleCodes | _DTypeLike[longdouble] | type[ctypes.c_longdouble]) -> type[ctypes.c_longdouble]:  # 返回值类型为 ctypes.c_longdouble 类型

def as_ctypes_type(dtype: _VoidDTypeLike) -> type[Any]:  # 返回值类型为任意类型,通常用于 ctypes.Union 或 ctypes.Structure

def as_ctypes_type(dtype: str) -> type[Any]:  # 返回值类型为任意类型,接受字符串参数

# 函数重载,将 ctypes 类型的对象转换为 NumPy 数组
def as_array(obj: ctypes._PointerLike, shape: Sequence[int]) -> NDArray[Any]:  # 接受 ctypes 指针对象和形状参数,返回 NumPy 数组

def as_array(obj: _ArrayLike[_SCT], shape: None | _ShapeLike = ...) -> NDArray[_SCT]:  # 接受数组对象和形状参数,返回 NumPy 数组

def as_array(obj: object, shape: None | _ShapeLike = ...) -> NDArray[Any]:  # 接受任意对象和形状参数,返回 NumPy 数组

# 函数重载,将 NumPy 对象转换为对应的 ctypes 类型
def as_ctypes(obj: np.bool) -> ctypes.c_bool:  # 将 NumPy 布尔值转换为 ctypes.c_bool 类型

def as_ctypes(obj: byte) -> ctypes.c_byte:  # 将 NumPy 字节值转换为 ctypes.c_byte 类型

def as_ctypes(obj: short) -> ctypes.c_short:  # 将 NumPy 短整数值转换为 ctypes.c_short 类型

def as_ctypes(obj: intc) -> ctypes.c_int:  # 将 NumPy 整数值转换为 ctypes.c_int 类型
# 将 long 类型对象转换为 ctypes.c_long 类型
@overload
def as_ctypes(obj: long) -> ctypes.c_long: ...

# 将 longlong 类型对象转换为 ctypes.c_longlong 类型
@overload
def as_ctypes(obj: longlong) -> ctypes.c_longlong: ...

# 将 ubyte 类型对象转换为 ctypes.c_ubyte 类型
@overload
def as_ctypes(obj: ubyte) -> ctypes.c_ubyte: ...

# 将 ushort 类型对象转换为 ctypes.c_ushort 类型
@overload
def as_ctypes(obj: ushort) -> ctypes.c_ushort: ...

# 将 uintc 类型对象转换为 ctypes.c_uint 类型
@overload
def as_ctypes(obj: uintc) -> ctypes.c_uint: ...

# 将 ulong 类型对象转换为 ctypes.c_ulong 类型
@overload
def as_ctypes(obj: ulong) -> ctypes.c_ulong: ...

# 将 ulonglong 类型对象转换为 ctypes.c_ulonglong 类型
@overload
def as_ctypes(obj: ulonglong) -> ctypes.c_ulonglong: ...

# 将 single 类型对象转换为 ctypes.c_float 类型
@overload
def as_ctypes(obj: single) -> ctypes.c_float: ...

# 将 double 类型对象转换为 ctypes.c_double 类型
@overload
def as_ctypes(obj: double) -> ctypes.c_double: ...

# 将 longdouble 类型对象转换为 ctypes.c_longdouble 类型
@overload
def as_ctypes(obj: longdouble) -> ctypes.c_longdouble: ...

# 将 void 类型对象转换为 ctypes.Union 或 ctypes.Structure 类型
@overload
def as_ctypes(obj: void) -> Any:  # `ctypes.Union` or `ctypes.Structure`
    ...

# 将 NDArray[np.bool] 类型对象转换为 ctypes.Array[ctypes.c_bool] 类型
@overload
def as_ctypes(obj: NDArray[np.bool]) -> ctypes.Array[ctypes.c_bool]: ...

# 将 NDArray[byte] 类型对象转换为 ctypes.Array[ctypes.c_byte] 类型
@overload
def as_ctypes(obj: NDArray[byte]) -> ctypes.Array[ctypes.c_byte]: ...

# 将 NDArray[short] 类型对象转换为 ctypes.Array[ctypes.c_short] 类型
@overload
def as_ctypes(obj: NDArray[short]) -> ctypes.Array[ctypes.c_short]: ...

# 将 NDArray[intc] 类型对象转换为 ctypes.Array[ctypes.c_int] 类型
@overload
def as_ctypes(obj: NDArray[intc]) -> ctypes.Array[ctypes.c_int]: ...

# 将 NDArray[long] 类型对象转换为 ctypes.Array[ctypes.c_long] 类型
@overload
def as_ctypes(obj: NDArray[long]) -> ctypes.Array[ctypes.c_long]: ...

# 将 NDArray[longlong] 类型对象转换为 ctypes.Array[ctypes.c_longlong] 类型
@overload
def as_ctypes(obj: NDArray[longlong]) -> ctypes.Array[ctypes.c_longlong]: ...

# 将 NDArray[ubyte] 类型对象转换为 ctypes.Array[ctypes.c_ubyte] 类型
@overload
def as_ctypes(obj: NDArray[ubyte]) -> ctypes.Array[ctypes.c_ubyte]: ...

# 将 NDArray[ushort] 类型对象转换为 ctypes.Array[ctypes.c_ushort] 类型
@overload
def as_ctypes(obj: NDArray[ushort]) -> ctypes.Array[ctypes.c_ushort]: ...

# 将 NDArray[uintc] 类型对象转换为 ctypes.Array[ctypes.c_uint] 类型
@overload
def as_ctypes(obj: NDArray[uintc]) -> ctypes.Array[ctypes.c_uint]: ...

# 将 NDArray[ulong] 类型对象转换为 ctypes.Array[ctypes.c_ulong] 类型
@overload
def as_ctypes(obj: NDArray[ulong]) -> ctypes.Array[ctypes.c_ulong]: ...

# 将 NDArray[ulonglong] 类型对象转换为 ctypes.Array[ctypes.c_ulonglong] 类型
@overload
def as_ctypes(obj: NDArray[ulonglong]) -> ctypes.Array[ctypes.c_ulonglong]: ...

# 将 NDArray[single] 类型对象转换为 ctypes.Array[ctypes.c_float] 类型
@overload
def as_ctypes(obj: NDArray[single]) -> ctypes.Array[ctypes.c_float]: ...

# 将 NDArray[double] 类型对象转换为 ctypes.Array[ctypes.c_double] 类型
@overload
def as_ctypes(obj: NDArray[double]) -> ctypes.Array[ctypes.c_double]: ...

# 将 NDArray[longdouble] 类型对象转换为 ctypes.Array[ctypes.c_longdouble] 类型
@overload
def as_ctypes(obj: NDArray[longdouble]) -> ctypes.Array[ctypes.c_longdouble]: ...

# 将 NDArray[void] 类型对象转换为 ctypes.Array[Any] 类型,可能是 `ctypes.Union` 或 `ctypes.Structure`
@overload
def as_ctypes(obj: NDArray[void]) -> ctypes.Array[Any]: ...

.\numpy\numpy\distutils\armccompiler.py

from distutils.unixccompiler import UnixCCompiler                              

class ArmCCompiler(UnixCCompiler):
    """
    Arm compiler subclass inheriting from UnixCCompiler.
    """

    # 设置编译器类型为 'arm'
    compiler_type = 'arm'
    # 设置 C 编译器可执行文件为 'armclang'
    cc_exe = 'armclang'
    # 设置 C++ 编译器可执行文件为 'armclang++'
    cxx_exe = 'armclang++'

    def __init__(self, verbose=0, dry_run=0, force=0):
        # 调用父类 UnixCCompiler 的初始化方法
        UnixCCompiler.__init__(self, verbose, dry_run, force)
        # 将 C 编译器可执行文件保存到 cc_compiler 变量中
        cc_compiler = self.cc_exe
        # 将 C++ 编译器可执行文件保存到 cxx_compiler 变量中
        cxx_compiler = self.cxx_exe
        # 设置编译器的各种参数及选项,以及链接器的选项
        self.set_executables(
            compiler=cc_compiler + ' -O3 -fPIC',        # 设置编译器命令及优化级别和位置无关代码
            compiler_so=cc_compiler + ' -O3 -fPIC',     # 设置用于编译源文件的编译器命令及优化级别和位置无关代码
            compiler_cxx=cxx_compiler + ' -O3 -fPIC',   # 设置用于编译 C++ 源文件的编译器命令及优化级别和位置无关代码
            linker_exe=cc_compiler + ' -lamath',        # 设置用于链接可执行文件的链接器命令及链接数学库
            linker_so=cc_compiler + ' -lamath -shared'  # 设置用于链接共享库的链接器命令及链接数学库和共享标志
        )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值