gpt4 book ai didi

python - 为什么 bytearray 不是 Python 2 中的序列?

转载 作者:太空狗 更新时间:2023-10-29 17:47:40 25 4
gpt4 key购买 nike

我发现 Python 2 和 3 之间存在奇怪的行为差异。

在 Python 3 中似乎工作正常:

Python 3.5.0rc2 (v3.5.0rc2:cc15d736d860, Aug 25 2015, 04:45:41) [MSC v.1900 32 b
it (Intel)] on win32
>>> from collections import Sequence
>>> isinstance(bytearray(b"56"), Sequence)
True

但不是在 Python 2 中:

Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on wi
n32
>>> from collections import Sequence
>>> isinstance(bytearray("56"), Sequence)
False

结果似乎在 Python 2.x 和 3.x 的次要版本中是一致的。这是一个已知的错误?这是一个错误吗?这种差异背后有什么逻辑吗?

我其实更担心C API函数PySequence_CheckPyByteArray_Type 类型的对象正确识别为公开序列协议(protocol),通过查看源代码似乎应该这样做,但非常欢迎任何对这整个事情的深入了解。

最佳答案

来自 collections 的抽象类使用 ABCMeta.register(subclass)

Register subclass as a “virtual subclass” of this ABC.

在 Python 3 中 issubclass(bytearray, Sequence)返回 True因为bytearray明确注册为 ByteString 的子类(源自 Sequence )和 MutableSequence .参见Lib/_collections_abc.py的相关部分:

class ByteString(Sequence):

"""This unifies bytes and bytearray.

XXX Should add all their methods.
"""

__slots__ = ()

ByteString.register(bytes)
ByteString.register(bytearray)
...
MutableSequence.register(bytearray) # Multiply inheriting, see ByteString

Python 2 不这样做(来自 Lib/_abcoll.py ):

Sequence.register(tuple)
Sequence.register(basestring)
Sequence.register(buffer)
Sequence.register(xrange)
...
MutableSequence.register(list)

此行为在 Python 3.0 中已更改(特别是在 this commit 中):

Add ABC ByteString which unifies bytes and bytearray (but not memoryview). There's no ABC for "PEP 3118 style buffer API objects" because there's no way to recognize these in Python (apart from trying to use memoryview() on them).

PEP 3119 中有更多信息:

This is a proposal to add Abstract Base Class (ABC) support to Python 3000. It proposes: [...] Specific ABCs for containers and iterators, to be added to the collections module.

Much of the thinking that went into the proposal is not about the specific mechanism of ABCs, as contrasted with Interfaces or Generic Functions (GFs), but about clarifying philosophical issues like "what makes a set", "what makes a mapping" and "what makes a sequence".

[...] a metaclass for use with ABCs that will allow us to add an ABC as a "virtual base class" (not the same concept as in C++) to any class, including to another ABC. This allows the standard library to define ABCs Sequence and MutableSequence and register these as virtual base classes for built-in types like basestring, tuple and list, so that for example the following conditions are all true: [...] issubclass(bytearray, MutableSequence).

仅供引用 memoryview已注册为 Sequence 的子类仅在 Python 3.4 中:

There's no ducktyping for this due to the Sequence/Mapping confusion so it's a simple missing explicit registration.

(有关详细信息,请参阅 issue18690)。


PySequence_Check 来自 Python C API 不依赖 collections模块:

int
PySequence_Check(PyObject *s)
{
if (PyDict_Check(s))
return 0;
return s != NULL && s->ob_type->tp_as_sequence &&
s->ob_type->tp_as_sequence->sq_item != NULL;
}

它检查非零 tp_as_sequence字段 ( example for bytearray ),如果成功,对于非零 sq_item字段(基本上是 getitem - example for bytearray )。

关于python - 为什么 bytearray 不是 Python 2 中的序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32258275/

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