为什么numpy.r_使用方括号而不是圆括号?

20

Numpy.r_、.c_ 和 .s_ 是我遇到的唯一几个可以使用方括号而不是圆括号作为参数的 Python 函数。这是为什么呢?这些函数有什么特别之处吗?我能否编写自己的使用方括号的函数(虽然我并不想要,只是好奇)?

例如,正确的语法是:

    np.r_['0,2', [1,2,3], [4,5,6]]

我本以为它会是这样的:

    np.r_('0,2', [1,2,3], [4,5,6])
1个回答

20

任何Python类都可以通过实现一个名为__call__的函数来接受圆括号,并通过实现__getitem__来接受方括号,或者同时接受这两种表示方法。

np.r_ 恰好是实现了__getitem__以执行比通常更复杂的操作的类。也就是说,r_的类(称为np.lib.index_tricks.RClass)会执行类似以下的操作:

class RClass:
    def __getitem__(self, item):
        # r_ fancyness

很可能是出于切片表示法的优势考虑,例如当你有一个列表(或np数组或任何实现此协议的对象)l时,你可以执行以下操作:

l[:5]

Python会自动创建一个slice对象来传递给__getitem__方法。

这种语法不能用于__call__ - 用户需要显式地创建切片,例如通过执行l(slice(5))

请注意,__call__方法可以接受任何你想传入的参数;而__getitem__总是只接受一个参数:当你像这样做 my_array[1:3, 2:5]时,Python传递单个包含多个切片的元组。但是,就像任何其他函数一样,正如你在r_中看到的那样,内容不限于数字和切片 - Python将乐意传递任何对象,并将其留给类来解释它的含义。


谢谢!我没有想到这只是标准语法。 - kdamica
然而,我不理解其目的,因为切片是在传递的数组内部。此外,如果这样做有优势,为什么我们没有经常看到它呢? - kdamica
@KennethD'Amica,你必须将 slice(start, stop, step) 作为函数调用的唯一其他选择传递进去。__getitem__ 是实现这一点的唯一方法,这并不是优势,而是一种巧妙的方式,但它只是为了方便而构建的,仅在测试代码时才真正需要。 - jamylak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接