web-dev-qa-db-fra.com

comment convertir Python 2 fonction unicode () en syntaxe correcte Python 3.x)

J'ai activé la vérification de compatibilité dans mon Python IDE et maintenant je me rends compte que le code hérité Python 2.7 a beaucoup de appels à unicode() qui ne sont pas autorisés dans Python 3.x.

J'ai regardé les docs de Python2 et je n'ai trouvé aucun indice sur la mise à niveau:

Je ne veux pas passer à Python3 maintenant, mais peut-être à l'avenir.

Le code contient environ 500 appels à unicode()

La façon de procéder?

Mise à jour

Le commentaire de l'utilisateur vaultah de lire le guide pyporting a reçu plusieurs votes positifs.

Ma solution actuelle est la suivante (merci à Peter Brittain):

from builtins import str

... Je ne pouvais pas trouver cette allusion dans les documents pyporting .....

12
guettli

Comme cela a déjà été souligné dans les commentaires, il y a déjà conseils sur le portage de 2 à .

Ayant récemment dû porter une partie de mon propre code de 2 à 3 et maintenir la compatibilité pour chacun pour l'instant, je recommande vivement d'utiliser python-future , qui fournit un excellent outil pour vous aider à mettre à jour votre code (futurize) ainsi que des instructions claires pour comment écrire du code compatible .

Dans votre cas spécifique, je convertirais simplement tous les appels en unicode pour utiliser str, puis importer str depuis les commandes intégrées . Tout IDE vaut son sel ces jours-ci fera cette recherche globale et le remplacera en une seule opération.

Bien sûr, c'est le genre de chose que futurize devrait également attraper, si vous souhaitez simplement utiliser la conversion automatique (et rechercher d'autres problèmes potentiels dans votre code).

21
Peter Brittain

Vous pouvez tester s'il existe une fonction telle que unicode() dans la version de Python que vous exécutez. Sinon, vous pouvez créer une unicode() alias de la fonction str(), qui fait en Python 3 ce que unicode() a fait en Python 2, comme toutes les chaînes sont unicode dans Python 3.

# Python 3 compatibility hack
try:
    unicode('')
except NameError:
    unicode = str

Notez qu'un port plus complet est probablement une meilleure idée; voir le guide de portage pour plus de détails.

8
Quint

Réponse courte: remplacez tous les appels unicode par des appels str.

Réponse longue: Dans Python 3, Unicode a été remplacé par des chaînes en raison de son abondance. La solution suivante devrait fonctionner si vous utilisez uniquement Python 3:

unicode = str
# the rest of your goes goes here

Si vous l'utilisez avec les deux Python 2 ou Python 3, utilisez-le à la place:

import sys
if sys.version_info.major == 3:
    unicode = str
# the rest of your code goes here

L'autre manière: exécutez ceci dans la ligne de commande

$ 2to3 package -w
5
user4913676

Tout d'abord, comme stratégie, je prendrais une petite partie de votre programme et j'essaierais de le porter. Le nombre d'appels unicode que vous décrivez me suggère que votre application se soucie des représentations de chaînes plus que la plupart et que chaque cas d'utilisation est souvent différent.

La considération importante est que toutes les chaînes sont en unicode dans Python. Si vous utilisez le type str pour stocker des "octets" (par exemple, s'ils sont lus à partir d'un fichier), vous devez savoir que ceux-ci ne seront pas des octets en Python3 mais seront des caractères unicode pour commencer.

Regardons quelques cas.

Tout d'abord, si vous n'avez aucun caractère non ASCII et que vous n'utilisez vraiment pas le jeu de caractères Unicode, c'est facile. Il y a de fortes chances que vous puissiez simplement changer la fonction unicode() en str(). Cela garantira que tout objet passé en argument est correctement converti. Cependant, c'est un vœu pieux de supposer que c'est aussi simple que cela.

Très probablement, vous devrez regarder l'argument de unicode() pour voir de quoi il s'agit et déterminer comment le traiter.

Par exemple, si vous lisez des caractères UTF-8 à partir d'un fichier en Python 2 et les convertissez en Unicode, votre code ressemblerait à ceci:

data = open('somefile', 'r').read()
udata = unicode(data)

Cependant, en Python3, read() retourne les données Unicode pour commencer, et le décodage unicode doit être spécifié lors de l'ouverture du fichier:

udata = open('somefile', 'r', encoding='UTF-8').read()

Comme vous pouvez le voir, la transformation de unicode() simplement lors du portage peut dépendre fortement de la manière et des raisons pour lesquelles l'application effectue des conversions Unicode, d'où proviennent les données et où elles vont.

Python3 apporte une plus grande clarté aux représentations de chaînes, ce qui est bienvenu, mais peut rendre le portage intimidant. Par exemple, Python3 a un type bytes approprié, et vous convertissez les données d'octet en unicode comme ceci:

udata = bytedata.decode('UTF-8')

ou convertissez les données Unicode en forme de caractères en utilisant la transformation opposée.

bytedata = udata.encode('UTF-8')

J'espère que cela aide au moins à déterminer une stratégie.

4
Gary Wisniewski