本文介绍了__getslice__弃用背后的基本原理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我想知道是否有人可以帮助我理解为什么__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__弃用背后的基本原理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 21:16
查看更多