检查“密钥”是否已存在的Pythonic/更快的方法是什么?自定义 __getitem__ 方法的参数是切片吗?
我有一个自定义序列类型。它本质上是一个列表加上布尔标志的包装器,我希望它能够模拟通常的不可变序列行为。
我的问题是切片。我知道在Python 3中实现它的方法是有一个 __getitem__(key) 方法,如果 %key
是单个索引,则返回一个项目,如果是切片序列,则返回一个项目%key
是一个切片对象。但我该如何区分这些情况呢?
我基本上有两个假设。
sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list
但这是邪恶的,不是吗?或者
sliced_list = self.wrapped_list[key]
try:
return MyCustomSequenceType(sliced_list, boolean_flag)
except TypeError:
return sliced_list
后者看起来更Pythonic。它依赖于 MyCustomSequenceType.__init__(self, datas, flag)
调用 len(datas) 的事实,因此如果 %datas
则引发 TypeError
是一个整数
。但是,如果 __init__
因另一个随机问题引发 TypeError
,它将无法追踪。另外 http://wiki.cython.org/enhancements/numpy/getitem 提示 < code>isinstance 更快(实际上更容易优化)。
那我该怎么办呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以查看标准库并复制那里所做的事情。例如,calendar.py 具有:
它显示了使用
isinstance
进行显式检查 和 通过简单地将索引或切片传递到底层列表来部分回避问题。You could have a look through the standard library and copy what is done there. For example, calendar.py has:
which shows both explicit checking with
isinstance
and partially ducking the issue by simply passing the index or slice through to the underlying list.这应该是
isinstance(key, slice)
,而不是isinstance(key, "slice")
。另外,您不应该直接调用
__getitem__
- 使用[]
项目符号。对于我自己来说,如果我需要辨别,我会使用 isinstance(key, slice) 方法 -
slice
是一个非常特殊的东西,而不是其他东西它很容易被其他类型替换(想一想 - 如果self.wrapped_list
是一个list
,那么slice
是唯一的类型将返回除元素之外的对象或 错误)。所以我最终会这样:
进一步考虑是否需要特殊处理切片;我不知道你的情况是什么,但是当做出一个会影响以后事情的架构决策时,通常最好考虑几种不同的方法来完成同一件事,并对它们进行评估并决定最好的一个(不是那个)我自己经常做这件事——我倾向于冲进去实施并随后修补......)。
That should be
isinstance(key, slice)
, notisinstance(key, "slice")
.Also, you shouldn't call
__getitem__
directly - use the[]
item notation.For myself, I would use the
isinstance(key, slice)
method if I needed to discern -slice
is a pretty special thing, not something that's easily going to be replaceable with another type (think about it - ifself.wrapped_list
is alist
, aslice
is the only type of object which will return other than an element or error).So I'd end up with it like this:
Consider further though whether you need to treat slices specially; I have no idea what your case is, but when making an architectural decision which will influence things later, it's generally a good idea to consider a few different ways of doing the same thing and evaluate them all and decide on the best one (not that I do it much myself - I tend to just rush in and implement and patch afterwards...).