Ani*_*iol 7 python list slice python-2.7 python-internals
我工作的Python 2.7和我试图超载 __getitem__,并__setitem__从继承的类list.
假设我有这个课程:
class A(list):
def __getitem__(self, key):
print "GET!"
def __setitem__(self, key, value):
print "SET!"
Run Code Online (Sandbox Code Playgroud)
用方括号A或A.__getitem__应调用.通常情况就是这样,但是当我使用A.__setitem__父实现时,会调用它.为什么?为什么[:]工作?
a = A([1])
a[1] # prints GET!
a["1"] # prints GET!
a[::] # prints GET!
a[slice(None)] # prints GET!
a[:] # returns the list [1]
Run Code Online (Sandbox Code Playgroud)
和以下一样[::]:
a[1] = 2 # prints SET!
a[::] = 2 # prints SET!
a[slice(None)] = 2 # prints SET!
a[:] = [2] # changes the list
Run Code Online (Sandbox Code Playgroud)
这是因为在Python 2 [1] [:],以及与1-d切片开始和/或结束(而不是当步骤指定的)像[1:],[:3]或[1:3]经过__getslice__和__setslice__如果它们被执行.如果他们没有实施,他们也会去__getitem__和__setitem__).引用文档:
请注意,
__*slice__仅当使用具有单个冒号的单个切片并且切片方法可用时,才会调用这些方法[ ].对于涉及扩展切片表示法的切片操作,或者没有切片方法__getitem__(),__setitem__()或者__delitem__()使用切片对象作为参数调用.
在你的情况下,你从(实现它们)继承它们,所以它绕过你和简单的切片情况.listlist__getitem____setitem__
例如,您可以覆盖__*slice__方法以验证[:]调用是否真的在那里:
class A(list):
def __getitem__(self, key):
print "GET!"
def __setitem__(self, key, value):
print "SET!"
def __getslice__(self, i, j):
print "GETSLICE!"
def __setslice__(self, i, j, seq):
print "SETSLICE!"
Run Code Online (Sandbox Code Playgroud)
但是,只有在传入一个切片时才会调用它们,并且只有在传递的切片没有步骤时才会调用它们.所以[::]不会去那里,因为它有一个步骤(即使它是隐含的).但也[:,:]不会进入这些因为它被翻译成tuple(slice(None), slice(None))不是一个简单的切片而是切片的元组.__*slice__如果你slice自己传递一个实例,它也不会进入这些方法,这就是为什么[slice(None)]即使看似相当于[:]直接进入__*item__而不是__*slice__.
[1]在Python 3 __*slice__中删除了方法,因此[whatever]索引将转到__*item__方法中.
| 归档时间: |
|
| 查看次数: |
154 次 |
| 最近记录: |