3 votes

Une façon plus efficace de faire des codes d'échappement unicode

J'utilise python pour générer automatiquement qsf fichiers pour les enquêtes en ligne Qualtrics. Le site qsf exige que les caractères unicode soient échappés à l'aide de la balise \u+hex convention : 'слово' = ' \u0441\u043b\u043e\u0432\u043e '. Actuellement, j'y parviens avec l'expression suivante :

'слово'.encode('ascii','backslashreplace').decode('ascii')

Le résultat est exactement ce dont j'ai besoin, mais comme il s'agit d'un processus en deux étapes, je me suis demandé s'il existait un moyen plus efficace d'obtenir le même résultat.

3voto

Neapolitan Points 1487

Si vous ouvrez votre fichier de sortie en tant que 'wb', il accepte un flux d'octets plutôt que des arguments unicode :

s = 'слово'
with open('data.txt','wb') as f:
    f.write(s.encode('unicode_escape'))
    f.write(b'\n')  # add a line feed

Cela semble faire ce que vous voulez :

$ cat data.txt
\u0441\u043b\u043e\u0432\u043e

et il évite à la fois le décodage et la traduction qui se produisent lors de l'écriture d'unicode dans un flux de texte.


Mis à jour pour utiliser encode('unicode_escape') selon la suggestion de @J.F.Sebastian.

%timeit rapporte qu'il est un peu plus rapide que encode('ascii', 'backslashreplace') :

In [18]: f = open('data.txt', 'wb')

In [19]: %timeit f.write(s.encode('unicode_escape'))
The slowest run took 224.43 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.55 µs per loop

In [20]: %timeit f.write(s.encode('ascii','backslashreplace'))
The slowest run took 9.13 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.37 µs per loop

In [21]: f.close()

Curieusement, le délai de timeit pour encode('unicode_escape') est beaucoup plus long que celui de encode('ascii', 'backslashreplace') même si le temps par boucle est plus rapide, donc assurez-vous de tester les deux dans votre environnement.

2voto

J.F. Sebastian Points 102961

Je doute que ce soit un goulot d'étranglement dans votre application mais s.encode('unicode_escape') peut être plus rapide que s.encode('ascii', 'backslashreplace') .

Pour éviter d'appeler .encode() manuellement, vous pourriez passer l'encodage à open() :

with open(filename, 'w', encoding='unicode_escape') as file:
    print(s, file=file)

Note : il traduit également les caractères ascii non imprimables, par exemple, un saut de ligne est écrit en tant que \n , onglet comme \t etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X