问题描述
大家好,
我想知道是否有人可以帮助我理解为什么__getslice__已经弃用了
,但仍然有必要实现它简单切片(i:j),
而__getitem__被调用扩展切片(i:j:k)。
这种方法的问题,除了一点代码重复,是实现切片的
类现在必须在内部执行运行时类型检查
__getitem__。这是一个简单的例子:
################################### #############################
导入类型
class Vector(list):
def __init __(self,arg,wrap = 0):
''''''
如果arg是一个整数,创建一个长度为n的新零向量。
否则,arg必须是一个python序列或另一个向量,
和一个新的(深层)副本是生成。
''''''
if isinstance(arg,int):
list .__ init __(self,[0.0] * arg)
else:
list .__ init __(self,arg)
def __getitem __(self,key):
"""调用单元素OR片段访问"""
如果type(key)是types.SliceType:
返回Vector(list .__ getitem __(self,key))
else:
返回列表.__ getitem __(自我,密钥)
def __getslice __(self,i,j):
"""自2.0以来已弃用,但仍被称为n扩展切片。
由于扩展切片由__getitem__处理,我只是将
推迟到那个切片,所以所有实际的实现都在那里完成。为什么这是
不是默认值(因为他们弃用了__getslice__)超出了我。""
返回self .__ getitem __(切片(i) ,j))
打印''a是矢量''
a =矢量(5)
打印
打印类型(a)
打印
打印''b是一片''
b = a [1:3]
打印b
打印类型(b)
打印
print''c是一个元素''
c = a [1]
打印c
打印类型(c)
####################################### #########################
我的错误是切片的类型检查似乎是必要的在__getitem__方法的
里面。我觉得如果我可以简单地使用__getslice__作为切片而使用__getitem__作为
项目,并且在这种混合模式下将两者捆绑在一起,那么代码将会更加清晰。 reall丑陋和
unpythonic。我只是遗漏了什么吗?
感谢您的帮助,
f
我不认为这是true - 一切都进入__getitem__:
(1,2,-1)
Steve
以防你认为他们不必做运行时
否则进行类型检查:
< type''list''> []
您可以在__getitem__中调用任何内容。你真的想要一个上面每个变种的方法吗?
史蒂夫
我不认为这个是真的 - 一切都进入__getitem__:
(slice(1,2,-1),){}
如果你继承了像list这样的内置类型,那就没有了:
在[6]中:类mylist(列表):
...:def __getitem __(self, * args,** kwds):
...:打印''mylist getitem''
......:print args,kwds
...:
在[7]中:a = mylist()
在[8]中:a [1]
mylist getitem
(1,){}
在[9]中:a [1:2]
Out [9]:[]
在[10]中:a [1:2:3]
mylist getitem
(切片(1,2,3),){}
我做了这个测试,这迫使我分别实现__getslice__
在我的小例子中,用简单的i:j切片来满足通话。
最好,
f
Hi all,
I was wondering if someone can help me understand why __getslice__ has been
deprecated, yet it remains necessary to implement it for simple slices (i:j),
while __getitem__ gets called for extended slices (i:j:k).
The problem with this approach, besides a bit of code duplication, is that
classes which implement slicing must now do runtime type-checking inside
__getitem__. Here''s a trivial example:
################################################## ##############
import types
class Vector(list):
def __init__(self,arg,wrap=0):
''''''
If arg is an integer, make a new zero vector of length n.
Otherwise, arg must be a python sequence or another vector,
and a new (deep) copy is generated.
''''''
if isinstance(arg,int):
list.__init__(self,[0.0]*arg)
else:
list.__init__(self,arg)
def __getitem__(self,key):
"""called for single-element OR slice access"""
if type(key) is types.SliceType:
return Vector(list.__getitem__(self,key))
else:
return list.__getitem__(self,key)
def __getslice__(self,i,j):
"""Deprecated since 2.0, but still called for non-extended slices.
Since extended slices are handled by __getitem__, I''m just deferring
to that one so all actual implementation is done there. Why this is
not the default (since they deprecated __getslice__) is beyond me."""
return self.__getitem__(slice(i,j))
print ''a is a vector''
a = Vector(5)
print a
print type(a)
print
print ''b is a slice of a''
b = a[1:3]
print b
print type(b)
print
print ''c is an element of a''
c = a[1]
print c
print type(c)
################################################## ##############
What bugs me is that typecheck for slicing which seems to be necessary inside
of the __getitem__ method. I have the feeling that the code would be much
cleaner if I could simply use __getslice__ for slices and __getitem__ for
items, and that bundling the two in this hybrid mode is reall ugly and
unpythonic. Am I just missing something?
Thanks for any help,
f
I don''t think this is true -- everything goes to __getitem__:
(1, 2, -1)
Steve
Just in case you thought that they wouldn''t have to do runtime
type-checking otherwise:
<type ''list''> []
You can put just about anything in a __getitem__ call. Do you really
want a method for each of the variants above?
Steve
I don''t think this is true -- everything goes to __getitem__:
(slice(1, 2, -1),) {}
Not if you subclass builtin types like list:
In [6]: class mylist(list):
...: def __getitem__(self,*args,**kwds):
...: print ''mylist getitem''
...: print args,kwds
...:
In [7]: a=mylist()
In [8]: a[1]
mylist getitem
(1,) {}
In [9]: a[1:2]
Out[9]: []
In [10]: a[1:2:3]
mylist getitem
(slice(1, 2, 3),) {}
I did this testing, which is what forced me to implement __getslice__
separately in my little example, to satisfy calls with simple i:j slices.
Best,
f
这篇关于__getslice__弃用背后的基本原理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!