为何向NumPy __array__方法传递关键字参数会报错?
解决
TypeError: __array__() takes 1 positional argument but 2 were given问题 这个报错的核心原因是numpy调用__array__方法时,会将额外参数以位置参数的形式传递,而非关键字参数。
问题根源
当你调用np.array(obj, dtype=np.float32)这类带参数的方法时,numpy内部并不是通过obj.__array__(dtype=np.float32)的方式调用,而是直接把dtype的值作为位置参数传给__array__,也就是执行obj.__array__(np.float32)。
这就导致了两种实现的差异:
- 用
**kwargs定义的__array__方法只能接收关键字参数,无法处理numpy传入的位置参数,因此触发参数数量不匹配的错误。 - 显式声明
dtype=None这类位置参数的实现,能正确接收numpy传递的参数,所以可以正常运行。
正确的实现方式
要兼容numpy的调用逻辑,你可以通过以下两种方式定义__array__:
方式1:遵循numpy规范声明位置参数
按照numpy官方规范,__array__的标准签名是__array__(self, dtype=None, /)(/表示位置-only参数),直接遵循这个规范即可:
import numpy as np class MyArray: def __init__(self, arr): self.arr = arr def __array__(self, dtype=None): return np.array(self.arr, dtype=dtype)
方式2:用*args接收所有位置参数
如果需要支持np.array函数的全部参数,也可以用*args和**kwargs组合,统一传递给内部的np.array,这种方式更灵活:
import numpy as np class MyArray: def __init__(self, arr): self.arr = arr def __array__(self, *args, **kwargs): return np.array(self.arr, *args, **kwargs)
关于“不符合Python风格”的疑问
numpy的这种设计源于早期Python版本的限制——当时还没有keyword-only参数的语法,因此采用了位置参数传递的方式。为了保持向后兼容性,numpy至今仍沿用这个调用逻辑,所以才会出现看似“不符合Python常规风格”的情况。
内容的提问来源于stack exchange,提问作者Ray Osborn
相关产品推荐
相关产品推荐

