根据numpy.r_
here上的numpy / scipy文档,它“不是函数,因此不需要参数”。
如果它不是一个函数,那么numpy.r_
等“函数”的正确用语是什么?
答案 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。在我看来,这是相当丑陋和令人困惑的!