Vérification de la documentation sur memoryview :
Les objets memoryviews permettent au code Python d'accéder aux données internes d'un qui supporte le protocole de tampon, sans avoir à le copier.
classe memoryview (obj)
Créez un memoryview qui fait référence à obj. obj doit supporter le protocole tampon. Objets intégrés qui prennent en charge le protocole des tampons incluent bytes et bytearray.
Ensuite, on nous donne l'exemple de code :
>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'
Citation terminée, regardons maintenant de plus près :
>>> 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
>>>
D'après ce que je comprends de ce qui précède :
Nous créons un objet memoryview pour exposer les données internes d'un objet tampon sans les copier. Toutefois, pour faire quoi que ce soit d'utile avec l'objet (en appelant les méthodes fournies par l'objet), nous devons créer une copie !
Habituellement, memoryview (ou l'ancien objet tampon) est nécessaire lorsque nous avons un objet de grande taille, et les tranches peuvent être grandes aussi. Le besoin d'une meilleure efficacité serait présent si nous faisons de grandes tranches, ou si nous faisons de petites tranches mais un grand nombre de fois.
Avec le schéma ci-dessus, je ne vois pas comment il peut être utile dans l'une ou l'autre situation, à moins que quelqu'un puisse m'expliquer ce que je manque ici.
Edit1 :
Nous avons un gros morceau de données, nous voulons le traiter en le parcourant du début à la fin. par exemple, extraire des tokens depuis le début d'un tampon de chaînes de caractères jusqu'à ce que le tampon soit épuisé. En C, cela revient à faire avancer un pointeur dans le tampon, et le pointeur peut être transmis à toute fonction qui attend le type de tampon. Comment peut-on faire quelque chose de similaire en Python ?
Les gens suggèrent des solutions de contournement, par exemple, de nombreuses fonctions de chaînes de caractères et de regex prennent des arguments de position. qui peuvent être utilisés pour émuler l'avancement d'un pointeur. Il y a deux problèmes avec cela : premièrement il s'agit d'une solution de contournement, vous êtes obligé de modifier votre style de codage pour pallier les inconvénients, et deuxièmement, toutes les fonctions n'ont pas d'arguments de position, par exemple les fonctions regex et les fonctions startswith
faire, encode()
/ decode()
ne le faites pas.
D'autres pourraient suggérer de charger les données par morceaux, ou de traiter la mémoire tampon en petits morceaux. segments plus grands que le jeton maximum. Ok, donc nous sommes conscients de ces possibles possibles, mais nous sommes censés travailler de façon plus naturelle en Python sans essayer de sans essayer d'adapter le style de codage au langage, n'est-ce pas ?
Edit2 :
Un exemple de code rendrait les choses plus claires. Voici ce que je veux faire, et ce que je pensais que memoryview me permettrait de faire à première vue. Utilisons pmview (proper memory view) pour la fonctionnalité que je recherche :
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