Подтвердить что ты не робот

Почему numpy.r_ использует скобки вместо скобок?

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])
4b9b3361

Ответ 1

Любой класс 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 будет счастливо проходить в любом объекте и оставить его классу для разработки того, что он означает.