Is there something internal in python that treats arguments passed to __getitem_
_
differently, and automatically converts start:stop:step
constructs into slices?
Here's a demonstration of what i mean
class ExampleClass(object):
def __getitem__(self, *args):
return args
def __call__(self, *args):
return args
def randomMethod(self, *args):
return args
a = ExampleClass()
#this works
print a[3:7:2, 1:11:2]
#syntax error on the first colon
print a.randomMethod(3:7:2, 1:11:2)
print a(3:7:2, 1:11:2)
#these work
print a.randomMethod(slice(3,7,2), slice(1,11,2))
print a(slice(3,7,2), slice(1,11,2))
Is it simply that the interpreter searches for instances of start:stop:step
inside []
, and swaps them out for slice(start, stop, step)
? The documentation simply says:
The bracket (subscript) notation uses slice objects internally
Is this one of the python internal bits that i can't alter the behaviour of? Is it possible to make other functions take slice objects usign the start:stop:step
shorthand?*
*I've seen the other question, Can python's slice notation be used outside of brackets?, but that just does it using a custom class, which i could easily do. What i want is a way to just use start:stop:step
without having to wrap it in anything else.
SIDE NOTE:
It also apears that all arguments inside [...]
are packaged up into a tuple
, somewhat as if it were doing [*args]
-> __getitem__(args)
.
class ExampleClass2(object):
def __getitem__(self, arg):
return arg
def __call__(self, arg):
return arg
b = ExampleClass2()
print b["argument 1", 2:4:6,3] # ('argument 1', slice(2, 4, 6), 3)
print b(slice(3,7,2), slice(1,11,2)) # TypeError: __call__() takes exactly 2 arguments (3 given)
np.lib.index_tricks
contains several 'functions' that accept this::
inputs, e.g.np.mgrid
,np.r_
,np.s_
.They are actually implemented as instances of classes, with
__getitem__
definitions. And they are 'called' with brackets.I don't normally use them, but they are an interesting example of how
__getitem__
can be exploited.np.insert
is an example of a function that generates indexing tuples that include slices.np.apply_along
also:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html has a relevant note:
The Python grammar defines when you can use the slice operator:
test
is pretty much any expression, but it is only inside asubscriptlist
that you can use the slice operator. So yes, the square brackets when used for subscripting are what matter, but square brackets used for lists won't magically allow you to write a slice, nor can you put a slice inside an arbitrary expression that just happens to be inside a subscript.If you want slices when you aren't subscripting something you'll have to write
slice(a,b,c)
.