为什么执行NumPy的r_[r_]代码会卡死?是预期行为还是Bug?
结论
这个卡死不属于NumPy的Bug,属于重载运算符的边界场景下的非预期但逻辑自洽的行为。
原因解释
numpy.r_不是普通函数,是RClass类的实例,它重载了__getitem__方法(也就是支持[]索引语法),设计目的是快速拼接生成数组,比如r_[1,2,3]会直接生成array([1, 2, 3])。- 当执行
r_[r_]时,r_的__getitem__方法收到的参数是r_实例本身,它会尝试先把传入的参数转换为NumPy数组。 - NumPy转换未知Python对象为数组时,会优先尝试迭代该对象:对于实现了
__getitem__的对象,会从索引0开始依次取obj[0]、obj[1]、obj[2]……直到捕获到IndexError才会停止迭代,用取到的所有值构造数组。 - 而
RClass的__getitem__对任意整数索引都能正常返回对应数组,永远不会抛出IndexError,就会触发无限迭代:NumPy会不停生成新的元素尝试构造数组,最终表现就是进程卡死、内存占用持续上涨。你可以简单验证这个逻辑:直接执行list(r_)也会出现完全一样的卡死现象。
内容的提问来源于stack exchange,提问作者Albert.Lang
相关产品推荐
相关产品推荐

