Gérer les accents

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je me pose quelques questions sur l'utilisation de caractères "hors ASCII" en Python 2.

En l'occurrence, j'utilise PyQt. Je demande à l'utilisateur de charger un nom de fichier via QtGui.QFileDialog.getOpenFileName. Ce nom, je veux l'afficher, l'utiliser pour ouvrir ledit fichier… Que faire si il contient des caractères non ASCII ? Faut-il utiliser unicode() ?

En fait, quelle structure de chaînes de caractères faut-il adopter lorsqu'il y a des caractères non ASCII ?

Merci. =)

+0 -0

QtGui.QFileDialog.getOpenFileName te renvois un QString. Il te faut le convertir en chaîne accepté par les autres fonctions python. En l’occurrence, puisque il peut contenir des caractères unicodes dedans, unicode() va te permettre de la transformer en chaine unicode python sans problème :

1
2
3
4
QSfileName = QFileDialog.getOpenFileName(...)
#QSfileName est de type QString
filename = unicode(QSfileName)
#filename est une chaine unicode classique de python

Si tu es sur du Python 2.7, normalement, toutes les fonctions ou presque acceptent des chaines unicode. Donc normalement tu ne devrait pas avoir de problèmes.

Si tu connais l'encodage (utf-8 souvent), ça fonctionne chez moi avec un fichier avec un accent :

1
2
Kje:~/test$ ls
toté.jpg

et dans python :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
>>> import cv2
>>> fn = u"toté.jpg"
>>> cv2.imread(fn)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 3: ordinal not in range(128)
>>> cv2.imread(fn.encode('utf-8'))
array([[[ 10,   4,   5],
        [ 11,   6,   7],
        [  0,   0,   0],
...
1
2
3
4
5
6
7
8
9
>>> toto = u"aéi"
>>> toto
u'a\xe9i'
>>> toto.encode("utf-8")
'a\xc3\xa9i'
>>> type(toto)
<type 'unicode'>
>>> type(toto.encode("utf-8"))
<type 'str'>

toto est là une chaine de type unicode. C'est typiquement ce que te renvoie unicode() qui converti ta QString. C'est un objet python utilisant la norme unicode pour représenter (tous les caractères).

toto.encode("utf-8") va demander de transformer cette chaine de caractère vers un encodage particulier et de mettre ça dans une chaine de caractère "classique" de python. Ces chaines (de type str) ne contiennent en réalité que des suites de d'octet et généralement encodé par defaut en ascii (7bits). Du coup, cela ne peut représenter tous les caractères et il faut la convertir vers un encodage particulier.

J'ai supposé, avec de la chance, que ton système utilisais de l'utf-8. En réalité une version plus propre et portable devrait être :

1
2
import sys
toto.encode(sys.stdin.encoding)

car sys.stdin.encoding te permet de connaître l'encodage par défaut du système.

NB: tu devrais peut être envisagé de passer à python3 + opencv 3 (en l'installant à la main depuis la branche dev actuel). La nouvelle version est beaucoup plus sympa et tu aura moins de problèmes d'encodage comme ça.

Merci beaucoup !

Je vais regarder OpenCV 3. Il y a des ressources à ce propos ? Tu mentionnes la branche "dev" : cela signifie-t-il que la version 3 est en développement - i.e. construction - ?

+0 -0

La doc est en cours de redaction et tu la trouve ici : http://docs.opencv.org/trunk/# et quelques tuto python http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html pour débuter.

Il y a forcément moins de trucs sur le net, puisque effectivement cette version n'est pas encore officiellement sortit. OpenCv 3 est principalement un gros ménage du code du coup il y a plusieurs trucs de cassé/différents. Mais le binding python est largement amélioré.

Pour information elle vient juste de passer en alpha donc on est encore assez loin de la sortie mais pour des dev perso je n'ai pas rencontré de probs avec.

Si tu n'y passe pas (c'est un peu chiant de toute la recompiler), regarde de temps en temps mon dernier liens pour voir quand ça va se stabiliser.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte