Qual é exatamente o ponto da visualização de memória em Python?
Verificando odocumentação no memoryview:
Os objetos memoryview permitem que o código Python acesse os dados internos de um objeto que suporta o protocolo de buffer sem copiar.
classevista de memória(obj)
Crie uma visão de memória que faça referência a obj. obj deve suportar o protocolo de buffer. Objetos internos que suportam o protocolo de buffer incluem bytes e bytearray.
Em seguida, recebemos o código de amostra:
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
Cotação acabou, agora vamos dar uma olhada:
>>> 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
>>>
Então, o que eu recordo do acima:
Criamos um objeto memoryview para expor os dados internos de um objeto buffer sem copiar, no entanto, para fazer qualquer coisa útil com o objeto (chamando os métodos fornecidos pelo objeto), temos que criar uma cópia!
Normalmente memoryview (ou o antigo objeto buffer) seria necessário quando temos um objeto grande, e as fatias podem ser grandes também. A necessidade de uma melhor eficiência estaria presente se estivéssemos fazendo fatias grandes, ou fazendo pequenas fatias, mas um grande número de vezes.
Com o esquema acima, eu não vejo como isso pode ser útil para qualquer situação, a menos que alguém possa me explicar o que estou perdendo aqui.
Edit1:
Nós temos um grande pedaço de dados, nós queremos processá-lo avançando através dele do começo ao fim, por exemplo extraindo tokens do começo de um buffer de string até que o buffer seja consumido. Em C term, isto está avançando um ponteiro através do buffer, e o ponteiro pode ser passado para qualquer função esperando o tipo de buffer. Como algo semelhante pode ser feito em python?
As pessoas sugerem soluções alternativas, por exemplo, muitas funções de cadeia de caracteres e de expressão regular recebem argumentos de posição que podem ser usados para emular o avanço de um ponteiro. Há dois problemas com isso: primeiro é uma solução, você é forçado a mudar seu estilo de codificação para superar as deficiências e, segundo: nem todas as funções têm argumentos de posição, por exemplo, funções de regex estartswith
Faz,encode()
/decode()
não faça
Outros podem sugerir carregar os dados em blocos ou processar o buffer em pequenos segmentos maiores que o token máximo. Ok, então estamos cientes dessas soluções possíveis, mas devemos trabalhar de forma mais natural em Python, sem tentar dobrar o estilo de codificação para encaixar na linguagem - não estamos?
Edit2:
Um exemplo de código tornaria as coisas mais claras. Isso é o que eu quero fazer, e o que eu supus que a visão da memória me permita fazer à primeira vista. Vamos usar pmview (visualização de memória adequada) para a funcionalidade que estou procurando:
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