[Tutor] 'slice', etc

eryksun eryksun at gmail.com
Sun Dec 15 06:46:42 CET 2013


On Fri, Dec 13, 2013 at 6:24 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
> On 07/12/2013 10:41, spir wrote:
>> On 12/07/2013 02:45 AM, Mark Lawrence wrote:
>>>
>>> The good news is there is a memoryview in Python, see
>>> http://docs.python.org/3/library/functions.html#func-memoryview.
>>> The bad news is it doesn't work on strings.
>>> See here for the slice object
>>> http://docs.python.org/3/library/functions.html#slice.
>>
>> Thank you, Mark, I'll have a look at memoryview, seems interesting anyway.
>
> I've just remembered that one distinct disadvantage of memoryviews is that
> you can't use them anywhere if you want to do any sorting, as you can't
> compare them :(

memorview requires the buffer interface, so that excludes 3.x str,
int, and many others. But it works for bytes, bytearray, mmap, ctypes,
and numpy to name just a few. Prior to 3.3, memoryview tests equality
using C memcmp, but not relative order. Sorting the raw buffers would
be arbitrary in general.

CPython 3.3's memoryview incorporates fast unpacking for primitive
types, and otherwise uses the struct module (but see issue 3132 about
updating struct for PEP 3118; this affects various ctypes data types).
Checking if memoryview objects are equal in 3.3 uses unpacked values,
which generally allows for a more meaningful comparison:

    from ctypes import c_int, c_float

    i, f = c_int(1), c_float(1)
    mi, mf = map(memoryview, (i, f))

    >>> mi == mf
    True

A memcmp of the primitive int and float buffers, as used prior to 3.3,
is clearly unequal:

    >>> list(map(int, bytes(i)))
    [1, 0, 0, 0]
    >>> list(map(int, bytes(f)))
    [0, 0, 128, 63]

It's not all roses, however. If memoryview in 3.3 fails to get a
struct unpacker, it doesn't default to using memcmp. It just assumes
inequality. This affects the view of a ctypes Array:

    >>> a = (c_int * 2)(1, 2)
    >>> b = (c_int * 2)(1, 2)
    >>> memoryview(a) == memoryview(b)
    False

The struct module doesn't know about the Array's PEP 3118 format string:

    >>> memoryview(a).format
    '(2)<i'

The '(n)' array syntax and mid-format '<' endian spec are new, and per
issue 3132, the struct module hasn't been updated to support them:

    >>> unpack = struct.Struct('(2)<i').unpack
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    struct.error: bad char in struct format

struct understands '<ii':

    >>> unpack = struct.Struct('<ii').unpack
    >>> unpack(a)
    (1, 2)


More information about the Tutor mailing list