简体   繁体   English

Python切片对象和__getitem__

[英]Python slice objects and __getitem__

Is there something internal in python that treats arguments passed to __getitem_ _ differently, and automatically converts start:stop:step constructs into slices? python中是否存在内容,以不同方式处理传递给__getitem_ _参数,并自动将start:stop:step构造转换为切片?

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) ? 只是解释器在[]搜索start:stop:step实例,并将它们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? 这是我不能改变行为的python内部位之一吗? Is it possible to make other functions take slice objects usign the start:stop:step shorthand?* 是否有可能使其他函数采用切片对象使用start:stop:step速记?*

*I've seen the other question, Can python's slice notation be used outside of brackets? *我已经看到了另一个问题, 可以在括号外使用python的切片表示法吗? , 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. 我想要的是一种只使用start:stop:step而不必将其包装在其他任何东西中。

SIDE NOTE: 边注:

It also apears that all arguments inside [...] are packaged up into a tuple , somewhat as if it were doing [*args] -> __getitem__(args) . 它也表明[...]内的所有参数都被打包成一个tuple ,就好像它正在做[*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)

The Python grammar defines when you can use the slice operator: Python语法定义何时可以使用切片运算符:

trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
subscript: test | [test] ':' [test] [sliceop]
sliceop: ':' [test]

test is pretty much any expression, but it is only inside a subscriptlist that you can use the slice operator. test几乎是任何表达式,但它只能在子subscriptlist中使用切片运算符。 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) . 如果你想要切片,当你没有订阅东西时,你必须写slice(a,b,c)

np.lib.index_tricks contains several 'functions' that accept this :: inputs, eg np.mgrid , np.r_ , np.s_ . np.lib.index_tricks包含几个接受this :: inputs的'函数',例如np.mgridnp.r_np.s_

They are actually implemented as instances of classes, with __getitem__ definitions. 它们实际上是作为类的实例实现的,具有__getitem__定义。 And they are 'called' with brackets. 他们被括号“称为”。

np.s_[2::2] #  slice(2, None, 2)
np.r_[-1:1:6j, [0]*3, 5, 6]  # array([-1. , -0.6, -0.2,  0.2, ... 6. ])
mgrid[0:5,0:5]

I don't normally use them, but they are an interesting example of how __getitem__ can be exploited. 我通常不会使用它们,但它们是如何利用__getitem__一个有趣例子。

np.insert is an example of a function that generates indexing tuples that include slices. np.insert是一个生成包含切片的索引元组的函数示例。 np.apply_along also: np.apply_along还:

i = zeros(nd, 'O')
...
i[axis] = slice(None, None)
...
i.put(indlist, ind)
...arr[tuple(i.tolist())]

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html has a relevant note: http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html有相关说明:

Remember that a slicing tuple can always be constructed as obj and used in the x[obj] notation. 请记住,切片元组总是可以构造为obj并在x[obj]表示法中使用。 Slice objects can be used in the construction in place of the [start:stop:step] notation. 可以在构造中使用切片对象代替[start:stop:step]表示法。 For example, x[1:10:5,::-1] can also be implemented as obj = (slice(1,10,5), slice(None,None,-1)); x[obj] 例如, x[1:10:5,::-1]也可以实现为obj = (slice(1,10,5), slice(None,None,-1)); x[obj] obj = (slice(1,10,5), slice(None,None,-1)); x[obj] . obj = (slice(1,10,5), slice(None,None,-1)); x[obj] This can be useful for constructing generic code that works on arrays of arbitrary dimension. 这对于构造适用于任意维数组的通用代码非常有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM