【问题标题】:numpy.r_ is not a function. What is it?numpy.r_ 不是函数。它是什么?
【发布时间】:2013-09-03 20:34:19
【问题描述】:

根据numpy.r_here 上的 numpy/scipy 文档,它“不是函数,因此不带参数”。

如果不是函数,那么numpy.r_等“函数”的专有名词是什么?

【问题讨论】:

    标签: python function numpy


    【解决方案1】:

    我认为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__ 方法的调用,其中冒号符号被转换为 slice 对象:

    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_ 对象“滥用”这一事实来创建一个接受切片表示法的“函数”,该函数还执行一些附加操作,例如将所有内容连接在一起并返回结果,以便您可以编写 x = np.r_[1:11, 15, 20:110:10]。文档中的“不是函数,所以不带参数”有点误导......

    【讨论】:

    • 在某种意义上归结为拥有__getitem__ 方法和__call__ 方法。 np.arraynp.r_[] 有前者,函数有后者。事实上,任何有__call__的对象都是可调用的。
    【解决方案2】:

    这是一个类实例(又名对象):

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

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

    类可以拥有的方法之一是__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)- 不是 em> 类/实例表现为函数 - 它是被调用的 myClass 实例的 __getitem__ 函数。

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

    【讨论】:

    • 它实际上是RClass 的一个实例,而不是一个类本身。
    • @RobertKern 你当然是对的,我已经修改了我的答案以反映这一点。
    • 你能在这里向其他人解释一下类的实例和类本身之间的区别吗?
    • 好的,完成,如果您认为需要进一步澄清,请告诉我。
    • stackoverflow.com/a/16755528/901925 解释说使用__getitem__ 代替__call__ 以利用slice 表示法。
    猜你喜欢
    • 2016-10-11
    • 2020-03-08
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    相关资源
    最近更新 更多