【发布时间】:2021-03-19 10:50:08
【问题描述】:
刚开始学习 OOP 以及方法和函数的区别。对一些非常基本的概念有一些困难。我的理解是,方法通常可以通过两种等效的方式调用。
object.method(parameters)
或
class.method(object, parameters)
问题为什么有些 numpy 方法可以使用这两种表示法调用,而其他方法似乎只能使用一种?例如,如果 A 和 B 都是相同长度的 numpy 数组,我可以将 numpy.dot 称为任一
np.dot(a,b)
或等效
a.dot(b)
但是对于 numpy.roll 或 numpy.insert 等某些方法(该方法对一个对象而不是两个对象进行操作),情况并非如此。
np.insert(a,[0],[1])
工作正常
a.insert([0],[1])
返回以下属性错误
AttributeError: 'numpy.ndarray' object has no attribute 'insert'
这是因为 np.dot 是特定于 ndarray 子类的方法,而 np.insert 可能是所有 numpy 对象的方法,这使得它实际上只能作为函数调用?
任何见解都会有所帮助,谢谢!
【问题讨论】:
-
理想情况下,所有相关的
numpy函数也将实现为ndarray方法,但这会在实现和更新时产生大量双重工作。我想他们只在以下情况下将函数实现为对象方法:1)这是一个非常常用的操作或(尤其是)2)当访问底层数据结构使方法比函数更有效时(就像ndarray.dot()) -
另外,让一切都成为一种方法可能会导致一些难以解析的冗长而密集的代码(请参阅
pandas,其中方法链接是地方性的) -
np.dot是一个函数。a.dot是一种方法。np.sum和a.sum相同,函数形式将其参数放入数组中,然后调用方法。np.insert是一个用 python 编写的函数,没有等效的编译方法。np.sin是一个ufunc函数,没有任何等效方法。 -
有一点额外的开销,但如果参数已经是一个数组,它是最小的,相当于调用
np.asarray(obj)。通常,您可以使用其中任何一种,具体取决于使您的代码最易读的原因。有时您必须使用其中一种。如果a是一个列表,则必须使用np.dot(a,b),但如果a是scipy.sparse矩阵,则使用a.dot(...)形式(或a@b运算符形式)。 -
在大图中,
numpy有大量编译的ndarray方法。其中许多还具有对应的函数,便于与非数组参数一起使用,并提供更多文档。但是也有很多函数没有等价的方法,有些是纯python,有些在特殊的ufunc类别中。operators也被翻译成方法调用。所有类别都有记录。