Bas*_*els 42
我认为,出于所有目的,它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))
Run Code Online (Sandbox Code Playgroud)
该r_对象"滥用"这一事实来创建一个"功能",接受片的符号,这也确实喜欢串联在一起的一切,返回的结果,这样就可以写一些额外的东西x = np.r_[1:11, 15, 20:110:10].文档中的"不是一个函数,所以没有参数"有点误导......
Mik*_*lla 36
它是一个类实例(也称为对象):
In [2]: numpy.r_
Out[2]: <numpy.lib.index_tricks.RClass at 0x1923710>
Run Code Online (Sandbox Code Playgroud)
类是用于定义不同类型的构造- 因为这样的类允许自身的实例.每个实例都可以具有属性(成员/实例变量和方法).
类可以拥有的__getitem__方法之一是方法,只要附加[something,something...something]到实例的名称,就会调用此方法.在numpy.r_实例的情况下,该方法返回一个numpy数组.
以下面的类为例:
class myClass(object)
def __getitem__(self,i)
return i*2
Run Code Online (Sandbox Code Playgroud)
查看上述类的这些输出:
In [1]: a = myClass()
In [2]: a[3]
Out[2]: 6
In [3]: a[3,4]
Out[3]: (3, 4, 3, 4)
Run Code Online (Sandbox Code Playgroud)
我正在调用__getitem__myClass 的方法(通过[]括号)并且__getitem__方法返回(在这种情况下列表*2的内容) - 它不是作为函数表现的类/实例 - 它是实例的__getitem__函数myClass被称为.
最后一点,你会注意到要实例化myClass我必须做的事情,a = myClass()而得到RClass你使用的实例numpy.r_这是因为numpy实例化RClass并将它绑定到名称numpy.r_本身.这是numpy源代码中的相关行.在我看来,这是相当丑陋和令人困惑的!