检查“密钥”是否已存在的Pythonic/更快的方法是什么?自定义 __getitem__ 方法的参数是切片吗?

发布于 2024-11-09 02:11:31 字数 1025 浏览 0 评论 0 原文

我有一个自定义序列类型。它本质上是一个列表加上布尔标志的包装器,我希望它能够模拟通常的不可变序列行为。

我的问题是切片。我知道在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 更快(实际上更容易优化)。

那我该怎么办呢?

I have a custom Sequence type. It is essentially a wrapper for a list plus a boolean flag and I wanted it to emulate usual immutable sequence behavior.

My issue is with slicing. I understand that in Python 3 the way to implement it is to have a __getitem__(key) method that returns an item if %key is a single index and a sliced sequence if %key is a slice object. But how should I discriminate these cases?

I basically have two hypotheses.

sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
    return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list

But this is evil, isn't it? Or

sliced_list = self.wrapped_list[key]
try:
    return MyCustomSequenceType(sliced_list, boolean_flag)
except TypeError:
    return sliced_list

The latter looks more pythonic. It relies on the fact that MyCustomSequenceType.__init__(self, datas, flag) calls len(datas), it so raise TypeError if %datas is an integer. But then, if __init__ raises TypeError for another random issue it will be untraceable. Also http://wiki.cython.org/enhancements/numpy/getitem hints that isinstance is faster (in fact more easily optimizable).

What should I do, then?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫相离 2024-11-16 02:11:31

您可以查看标准库并复制那里所做的事情。例如,calendar.py 具有:

def __getitem__(self, i):
    funcs = self._months[i]
    if isinstance(i, slice):
        return [f(self.format) for f in funcs]
    else:
        return funcs(self.format)

它显示了使用 isinstance 进行显式检查 通过简单地将索引或切片传递到底层列表来部分回避问题。

You could have a look through the standard library and copy what is done there. For example, calendar.py has:

def __getitem__(self, i):
    funcs = self._months[i]
    if isinstance(i, slice):
        return [f(self.format) for f in funcs]
    else:
        return funcs(self.format)

which shows both explicit checking with isinstance and partially ducking the issue by simply passing the index or slice through to the underlying list.

落在眉间の轻吻 2024-11-16 02:11:31

这应该是 isinstance(key, slice),而不是 isinstance(key, "slice")

另外,您不应该直接调用 __getitem__ - 使用 [] 项目符号。

对于我自己来说,如果我需要辨别,我会使用 isinstance(key, slice) 方法 - slice 是一个非常特殊的东西,而不是其他东西它很容易被其他类型替换(想一想 - 如果 self.wrapped_list 是一个 list,那么 slice 是唯一的类型将返回除元素之外的对象或 错误)。

所以我最终会这样:

sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
    return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list

进一步考虑是否需要特殊处理切片;我不知道你的情况是什么,但是当做出一个会影响以后事情的架构决策时,通常最好考虑几种不同的方法来完成同一件事,并对它们进行评估并决定最好的一个(不是那个)我自己经常做这件事——我倾向于冲进去实施并随后修补......)。

That should be isinstance(key, slice), not isinstance(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 - if self.wrapped_list is a list, a slice is the only type of object which will return other than an element or error).

So I'd end up with it like this:

sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
    return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list

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...).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文