В соответствии с документом numpy/scipy на numpy.r_
here, он «не является функцией, поэтому не принимает параметров».numpy.r_ не является функцией. Что это?
Если это не функция, то каков правильный термин для «функций», таких как numpy.r_
?
В соответствии с документом numpy/scipy на numpy.r_
here, он «не является функцией, поэтому не принимает параметров».numpy.r_ не является функцией. Что это?
Если это не функция, то каков правильный термин для «функций», таких как numpy.r_
?
Это экземпляр класса (он же объект):
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)
Я звоню __getitem__
метод MyClass (через []
скобках) и __getitem__
метод возвращается (содержимое списка * 2 в этом случае) - это не класс/экземпляр ведет себя как функция - это функция __getitem__
e myClass
экземпляр, который вызывается.
На заключительной ноте, вы заметите, что экземпляр myClass
я должен был сделать a = myClass()
тогда, чтобы получить экземпляр RClass
вы используете numpy.r_
Это потому, что NumPy конкретизирует RClass
и связывает его с именем numpy.r_ себе. This is the relevant line in the numpy source code. По-моему, это довольно уродливо и сбивает с толку!
Я бы сказал, что для всех целей r_
есть функция, но одна реализована умным взломом с использованием другого синтаксиса. Майк уже объяснил, как 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))
The r_
объекта «злоупотребление» этот факт, чтобы создать " функция ", которая принимает нотацию фрагмента, которая также выполняет некоторые дополнительные вещи, такие как объединение всех вместе и возвращение результата, так что вы можете написать x = np.r_[1:11, 15, 20:110:10]
. «Не функция, поэтому не принимает никаких параметров» в документации немного вводит в заблуждение ...
В некотором смысле это сводится к методу '__getitem__' и методу' __call__'. 'np.array',' np.r_' и '[]' имеют первое, функция имеет более позднюю. На самом деле любой объект может быть вызван, если он имеет '__call__'. – hpaulj
Отличная перспектива! –
Это на самом деле экземпляр «RClass», а не сам класс. –
@RobertKern. Вы, конечно, правы, я внесла поправки в свой ответ, чтобы отразить это. –
Можете ли вы объяснить окружающим, что же такое разница между экземпляром класса и самим классом? – usethedeathstar