Comprobando la documentación en memoryview:
Los objetos memoryview permiten que el código Python acceda a los datos internos de un objeto que admita el protocolo de búfer sin copiar.
clase memoryview (obj)
Cree una vista de memoria que haga referencia a obj. obj debe admitir el protocolo de búfer. Los objetos integrados que admiten el protocolo de búfer incluyen bytes y bytearray.
Luego se nos da el código de muestra:
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
Cita terminada, ahora echemos un vistazo más de cerca:
>>> b = b'long bytes stream'
>>> b.startswith(b'long')
True
>>> v = memoryview(b)
>>> vsub = v[5:]
>>> vsub.startswith(b'bytes')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'memoryview' object has no attribute 'startswith'
>>> bytes(vsub).startswith(b'bytes')
True
>>>
Entonces, lo que deduzco de lo anterior:
Creamos un objeto memoryview para exponer los datos internos de un objeto búfer sin copiar, sin embargo, para hacer algo útil con el objeto (llamando a los métodos proporcionados por el objeto), ¡tenemos que crear una copia!
Por lo general, la vista de memoria (o el antiguo objeto de búfer) sería necesaria cuando tenemos un objeto grande, y los cortes también pueden ser grandes. La necesidad de una mayor eficiencia estaría presente si estamos haciendo rodajas grandes, o haciendo rodajas pequeñas pero un gran número de veces.
Con el esquema anterior, no veo cómo puede ser útil para ninguna de las situaciones, a menos que alguien pueda explicarme qué me estoy perdiendo aquí.
Edición 1:
Tenemos una gran cantidad de datos, queremos procesarlos avanzando a través de ellos de principio a fin, por ejemplo, extrayendo tokens desde el inicio de un búfer de cadena hasta que el búfer se consume. búfer, y el puntero se puede pasar a cualquier función que espere el tipo de búfer. ¿Cómo se puede hacer algo similar en Python?
La gente sugiere soluciones alternativas, por ejemplo, muchas funciones de cadena y expresiones regulares toman argumentos de posición que se pueden usar para emular el avance de un puntero. Hay dos problemas con esto: primero es una solución alternativa, se ve obligado a cambiar su estilo de codificación para superar las deficiencias, y segundo: no todas las funciones tienen argumentos de posición, por ejemplo, funciones regex y startswith
do, encode()
/ decode()
don't.
Otros pueden sugerir cargar los datos en fragmentos o procesar el búfer en segmentos pequeños más grandes que el token máximo. De acuerdo, somos conscientes de estas posibles soluciones, pero se supone que debemos trabajar de una manera más natural en Python sin intentar modificar el estilo de codificación para que se ajuste al lenguaje, ¿no es así?
Edición 2:
Una muestra de código aclararía las cosas. Esto es lo que quiero hacer y lo que asumí que memoryview me permitiría hacer a primera vista. Usemos pmview (vista de memoria adecuada) para la funcionalidad que estoy buscando:
tokens = []
xlarge_str = get_string()
xlarge_str_view = pmview(xlarge_str)
while True:
token = get_token(xlarge_str_view)
if token:
xlarge_str_view = xlarge_str_view.vslice(len(token))
# vslice: view slice: default stop paramter at end of buffer
tokens.append(token)
else:
break