IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Probléme D'encodage ASCII


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 27
    Points : 16
    Points
    16
    Par défaut Probléme D'encodage ASCII
    Bonjour,

    J'ai eu de multiple problème d'encodage avec pyhton que je toujours put résoudre mais là j'y comprend rien.



    Je récupére un fichier CSV :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.LeFichierCSV = codecs.open(self.CheminFichier,"r", "cp1252")
    Puis j'utilise CSV Reader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.ReaderFichierCSV = csv.reader(self.LeFichierCSV, delimiter=';')
    Sur Mac pas de soucis, sous windows :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    2012-03-22 18:03:57:ERROR:STDERR:Traceback (most recent call last):
    2012-03-22 18:03:57:ERROR:STDERR:File "app.py", line 118, in function
    2012-03-22 18:03:57:ERROR:STDERR:UnicodeEncodeError
    2012-03-22 18:03:57:ERROR:STDERR:'ascii' codec can't encode character u'\xe9' in position 5: ordinal not in range(128)
    J'utilise exactement les mêmes fichiers CSV d'un OS à l'autre.
    De plus si je fais affiché self.LeFichierCSV Je n'ai pas d'erreur d'encodage. Les accent son affiché correctement.
    J'y comprend rien....

    NB: mon application est développe sur un mac pour être utilisé sur windows.

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je suppose que c'est sous Python 2.7.

    Sous Python 2.7, le module csv a un gros problème: il ne supporte pas l'unicode. De ce fait, la solution avec le module codecs n'est pas recommandée puisque les lignes lues sont alors en unicode. Il est d'ailleurs curieux que ça fonctionne quand même la plupart du temps...

    En tout cas, ce n'est pas la solution recommandée par la doc. Dans cette doc du module csv, il y a une solution en fin de page, mais qui est difficile à comprendre (http://docs.python.org/library/csv.html#module-csv).

    En fait, si on est sous Windows, on veut lire un fichier csv encodé cp1252, et on veut recevoir en mémoire un fichier dont les chaines sont en unicode (ou n'importe quoi d'autre!). Mais la seule chose que le module csv sait bien faire, c'est: lire de l'utf-8, et restituer de l'utf-8!

    Alors, essaie un code comme le suivant. Son principe est simple:
    - ouverture du fichier csv avec codecs (donc lignes lues en unicode)
    - ré-encodage de ces lignes en utf-8
    - écriture dans un "faux" fichier en mémoire (cStringIO)
    - et c'est ce fichier en mémoire qu'on passe en lecture au module csv
    - on reçoit donc de csv des lignes encodées utf-8 qu'on peut ré-encoder comme on veut
    - et on retourne la liste obtenue

    On devrait pouvoir modifier ce code pour obtenir un itérateur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # python v2.7
     
    import csv, codecs, cStringIO
     
    #############################################################################
    class Excelin(csv.Dialect):
        """Profil de lecture de fichiers .csv en provenance d'Excel"""
        delimiter = ';'
        quotechar = '"'
        doublequote = True
        skipinitialspace = False
        lineterminator = '\r\n'
        quoting = csv.QUOTE_MINIMAL 
        # autres possibilités pour quoting:
        # csv.QUOTE_ALL, csv.QUOTE_NONNUMERIC csv.QUOTE_MINIMAL csv.QUOTE_NONE 
     
    excelin = Excelin()
    csv.register_dialect('excelin', excelin)
     
    #############################################################################
    def lireCSV(fichier, dialecte='excelin', codisk='cp1252', codram='unicode'):
        """lit un fichier csv encodé 'codisk' sur disque 
           et retourne la liste complète avec les chaines encodées 'codram'
        """
        f = codecs.open(fichier, 'r', codisk)
        fs = cStringIO.StringIO()
        for ligne in f:
            fs.write(ligne.encode('utf-8'))
        fs.seek(0) # pour remettre le curseur au début du fichier
        liste = []
        for ligne in csv.reader(fs, dialecte):
            nouvligne = []
            for elem in ligne:
                if isinstance(elem, str):
                    elem = elem.decode('utf-8') # encodage en unicode
                    if codram != 'unicode':
                        elem = elem.encode(codram) # ré-encodage 'codram'   
                nouvligne.append(elem)    
            liste.append(nouvligne)         
        return liste
     
    #############################################################################
    if __name__ == "__main__":
        fichier = "monfichier.csv"
        liste = lireCSV(fichier, codisk='cp1252')
        for ligne in liste:
            print ligne
    Attention: pour les encodages, il peut y avoir un 2ème problème très différent: celui de l'affichage! Dans certains cas, il faut réencoder les chaines à afficher en fonction de l'encodage de la console: sys.stdout.encoding. Ceci d'autant plus que les chaines à afficher se trouvent à l'intérieur d'une liste.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    Je te remercie infiniment pour cette réponse très efficace..

    Je vais voir comment je vais m’arranger de ce problème épineux.
    Ça m’ennuierais d'en arriver à de tel extrémité.

    Je vais considéré le problème calmement. Ça va prendre du temps alors je vais mettre le sujet en résolu.

    En tous les cas merci pour ta réponse super compléte .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème d'encodage ascii
    Par khadi8 dans le forum Général Python
    Réponses: 1
    Dernier message: 12/04/2014, 22h30
  2. Problème d'encodage ascii
    Par Milowen dans le forum C++Builder
    Réponses: 7
    Dernier message: 01/01/2014, 16h41
  3. Problème d'encodage en Unicode
    Par Skreo dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 28/12/2005, 10h43
  4. Problème d'encodage sur MySql 4.1
    Par Blanchet dans le forum Outils
    Réponses: 1
    Dernier message: 04/12/2005, 04h53
  5. [XML::PARSER] Problème d'encodage
    Par frangin2003 dans le forum Modules
    Réponses: 13
    Dernier message: 05/09/2005, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo