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.