numpy.r_不是函数。它是什么?

时间:2013-09-03 20:34:20

标签: python function numpy

根据numpy.r_ here上的numpy / scipy文档,它“不是函数,因此不需要参数”。

如果它不是一个函数,那么numpy.r_等“函数”的正确用语是什么?

2 个答案:

答案 0 :(得分:38)

我认为,出于所有目的,r_ 一个函数,但是一个由使用不同语法的聪明黑客实现的函数。 Mike已经解释了r_实际上不是一个函数,而是一个RClass的类实例,它实现了__getitem__,因此您可以将其用作r_[1]。不同之处在于您使用方括号而不是弯曲括号,因此您不进行函数调用,但实际上是在索引对象。虽然这在技术上是正确的,但就其所有目的而言,它的工作方式与函数调用类似,但允许正常函数不允许的一些额外语法。

创建r_的动机可能来自Matlab的语法,它允许以非常紧凑的方式构造数组,如x = [1:10, 15, 20:10:100]。要在numpy中实现同样的目标,您必须执行x = np.hstack((np.arange(1,11), 15, np.arange(20,110,10)))。在python中不允许使用冒号来创建范围,但它们确实以切片表示法的形式存在,以索引到列表,如L[3:5],甚至A[2:10, 20:30]用于多维数组。在引擎盖下,这些索引表示法转换为对对象的__getitem__方法的调用,其中冒号表示法转换为切片对象:

In [13]: class C(object):
    ...:     def __getitem__(self, x):
    ...:         print x

In [14]: c = C()

In [15]: c[1:11, 15, 20:110:10]
(slice(1, 11, None), 15, slice(20, 110, 10))

r_对象'滥用'这个事实来创建一个接受切片表示法的'函数',这也做了一些额外的事情,比如将所有内容连接在一起并返回结果,这样你就可以编写{{1} }。文档中的“不是一个函数,所以没有参数”有点误导......

答案 1 :(得分:32)

这是一个类实例(也称为对象):

In [2]: numpy.r_
Out[2]: <numpy.lib.index_tricks.RClass at 0x1923710>

类是一个用于定义不同类型的构造 - 因为这样的类允许实例本身。每个实例都可以具有属性(成员/实例变量和方法)。

类可以使用的方法之一是__getitem__方法,只要将[something,something...something]附加到实例的名称,就会调用此方法。在numpy.r_实例的情况下,该方法返回一个numpy数组。

以下面的课程为例:

class myClass(object)
    def __getitem__(self,i)
    return i*2

查看上述类的这些输出:

In [1]: a = myClass()

In [2]: a[3]
Out[2]: 6

In [3]: a[3,4]
Out[3]: (3, 4, 3, 4)

我正在调用myClass的__getitem__方法(通过[]括号)并返回__getitem__方法(在这种情况下,列表* 2的内容) - 它是表示为函数的类/实例 - 它是被调用的__getitem__实例的myClass函数。

最后一点,您会注意到要实例化myClass我必须a = myClass()而要获取RClass的实例,您使用numpy.r_这是因为numpy实例化RClass并将其绑定到名称numpy.r_本身。 This is the relevant line in the numpy source code。在我看来,这是相当丑陋和令人困惑的!