gpt4 book ai didi

python - 制作一个行为类似于切片的对象

转载 作者:太空狗 更新时间:2023-10-29 22:18:15 25 4
gpt4 key购买 nike

我们如何让一个类在适当的时候将自己表示为一个切片?

这没有用:

class MyThing(object):
def __init__(self, start, stop, otherstuff):
self.start = start
self.stop = stop
self.otherstuff = otherstuff
def __index__(self):
return slice(self.start, self.stop)

预期输出:

>>> thing = MyThing(1, 3, 'potato')
>>> 'hello world'[thing]
'el'

实际输出:

TypeError: __index__ returned non-(int,long) (type slice)

slice 继承也不起作用。

最佳答案

TLDR:不可能让自定义类替换内置类型的 slice,例如 listtuple


__index__ 方法的存在纯粹是为了提供一个 index,根据定义,它是 python 中的一个整数(参见 the Data Model )。您不能使用它来将对象解析为 slice

恐怕slice 好像是python专门处理的。该接口(interface)需要一个实际的切片;提供其签名(还包括 indices 方法)是不够的。正如您所发现的,您无法继承它,因此您无法创建新类型的 slice。即使是 Cython 也不允许您继承它。


那么为什么 slice 很特别呢?很高兴你问。欢迎来到 CPython 的内部。阅读后请洗手。

所以 slice 对象在 slice.rst 中有描述.注意这两个家伙:

.. c:var:: PyTypeObject PySlice_Type

The type object for slice objects. This is the same as :class:slice in the Python layer.

.. c:function:: int PySlice_Check(PyObject *ob) Return true if ob is a slice object; ob must not be NULL.

现在,这实际上是在sliceobject.h中实现的作为:

#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type)

所以只有 slice 类型在这里被允许。此检查实际用于 list_subscript (和 tuple subscript, ...) after 尝试使用索引协议(protocol)(因此在切片上使用 __index__ 是个坏主意)。自定义容器类可以自由覆盖 __getitem__ 并使用其自己的规则,但这就是 list(和 tuple,...)的做法.

现在,为什么不能子类化 slice?好吧,type 实际上有一个标志,指示某些东西是否可以被子类化。检查here并生成您看到的错误:

    if (!PyType_HasFeature(base_i, Py_TPFLAGS_BASETYPE)) {
PyErr_Format(PyExc_TypeError,
"type '%.100s' is not an acceptable base type",
base_i->tp_name);
return NULL;
}

我无法追踪到 slice (un) 是如何设置这个值的,但是一个人得到这个错误的事实意味着它确实如此。这意味着您不能对其进行子类化。


结束语:在记住了一些早已被遗忘的 C-(非)- 技能之后,我相当确定这不是严格意义上的优化。所有现有的检查和技巧仍然有效(至少我发现的那些)。

在洗手并在互联网上四处搜索后,我发现了一些类似“问题”的引用资料。 Tim Peters has said all there is to say:

Nothing implemented in C is subclassable unless somebody volunteers the work to make it subclassable; nobody volunteered the work to make the [insert name here] type subclassable. It sure wasn't at the top of my list wink.

另见 this thread有关不可子类化类型的简短讨论。

实际上所有替代解释器都在不同程度上复制了行为:Jython , Pyston , IronPython和 PyPy(不知道他们是如何做到的,但他们做到了)。

关于python - 制作一个行为类似于切片的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39971030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com