Any Python class can be made so that its instances accept either or both notation: it will accept parens by implementing a function called __call__
, and brackets by implementing __getitem__
.
np.r_
happens to be of a class that implements __getitem__
to do fancier things than its usual. That is, the class of r_
(called np.lib.index_tricks.RClass
) does something like this:
class RClass:
def __getitem__(self, item):
# r_ fancyness
Likely, this was done so that it can take advantage of slice notation - eg, when you have a list (or np array or any other object implementing this protocol) l
, and you do:
l[:5]
, Python automatically creates a slice
object to pass to __getitem__
.
This syntax doesn't work with __call__
- a user would have to create the slice explicitly, by doing l(slice(5))
.
Note that __call__
can take whatever arguments you like; while __getitem__
always takes exactly one argument: when you do something like my_array[1:3, 2:5]
, Python passes in a single tuple of slices. But, as you see with r_
, the contents aren't restricted to numbers and slices - similarly to any other function, Python will happily pass in any object and leave it to the class to work out what it means.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…