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 :

Faire un cast tuple -> list


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut Faire un cast tuple -> list
    Bonjour à tous,

    Dans un de mes programmes je dois lire un fichier Excel.
    Je le fais via le code suivant :

    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
    def readxlsfile(fichier_xls):
        excel = win32com.client.Dispatch('Excel.Application')
     
        classeur = excel.Workbooks.Open(fichier_xls)
        feuille = classeur.ActiveSheet             #On recupere la feuille courante
        maxcol = feuille.UsedRange.Columns.Count    #Recupere le nombre de colonne maximum
        maxline = feuille.UsedRange.Rows.Count      #Recupere le nombre de ligne maximum
     
        sht = classeur.Worksheets(feuille.name)
        donnees_lues = sht.Range(sht.Cells(1, 1), sht.Cells(maxline, maxcol)).Value
     
        donnees_lues = list(donnees_lues)
     
        #donnees_lues est une matrice de type "tuple" de "tuple"
        #Pour faciliter le traitement par la suite on la convertit en matrice de "list" de "list"
        #Pour finir on convertit chaque case de la matrice en chaîne de caractère
        for i in range(len(donnees_lues)):
            donnees_lues[i]=list(donnees_lues[i])
            del donnees_lues[i][0]      #on supprime la colonne 1
            del donnees_lues[i][3]      #on supprime la colonne 5
            j = 0
            while j < len(donnees_lues[i]):
                donnees_lues[i][j]=str(donnees_lues[i][j])
                j = j + 1
     
        #
        excel.Workbooks.Close()
        excel.Quit()
        del excel
        return donnees_lues
    Le problème c'est que dès qu'il y a un caractère accentué (comme "é, è, ê, ë, à, ù, ...") ou "exotique" (comme "@, °, µ, £, $, ¤, &, `, §, ç, ...") mon script plante et refuse de continuer en me disant ce message d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Traceback (most recent call last):
      File "C:\xxxx\script.py", line 98, in readxlsfile
        donnees_lues[i][j]=str(donnees_lues[i][j])
    UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)
    .
    --> Par exemple ici c'est un "é" que le programme ne peut pas transformer en caractère.

    C'est le cast du tuple en list qui plante. Mais la question est comment faire pour que ça fonctionne?


    Merci pour votre aide

    ffets

  2. #2
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    C'est plutôt un problème d'unicode:
    => http://python.developpez.com/faq/?page=Unicode

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        donnees_lues = list(donnees_lues)
        
        #donnees_lues est une matrice de type "tuple" de "tuple"
        #Pour faciliter le traitement par la suite on la convertit en matrice de "list" de "list"
        #Pour finir on convertit chaque case de la matrice en chaîne de caractère
        for i in range(len(donnees_lues)):
            donnees_lues[i]=list(donnees_lues[i])
            del donnees_lues[i][0]      #on supprime la colonne 1
            del donnees_lues[i][3]      #on supprime la colonne 5
            j = 0
            while j < len(donnees_lues[i]):
                donnees_lues[i][j]=str(donnees_lues[i][j]).encode('iso-8859-15')
                j = j + 1
    Merci Guigui_ pour ta réponse. D'après ce que j'ai compris j'ai une chaine unicode à la lecture et il faut que je la mette en chaine normale.
    Pour cela j'ai utilisé la méthode précisée sur le lien que tu m'a donné mais je n'obtient pas de résultat concluant. (le code transformé est en rouge)

    Mais toujours cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    donnees_lues[i][j]=str(donnees_lues[i][j]).encode('iso-8859-15')
    UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)
    .

    Peux-tu me dire ce que j'ai mal fait?

    Merci

    ffets

  4. #4
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    tu peux essayer ceci (c'est pas sûr que cela fonctionne):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    donnees_lues[i][j]=donnees_lues[i][j].encode('iso-8859-15')
    ce qui pose problème est d'appliquer la fonction str à une chaîne unicode

    Sinon fait une recherche sur le forum avec le mot "excel" et tu trouveras d'autres sujets traitant des mêmes problèmes

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Ca ne marche pas sans le str().

    J'avais cherché une première fois sur le forum avant de poster. Peut être pas assez je vais réinvestiguer !

    S'il y a d'autres pistes je suis preneur !

    A+

    ffets

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Après avoir cherché unicode sur le forum j'ai trouvé ce que je voulais :
    Apparemment pytho encode en ascii par défaut les chaines de caractères traitées.

    Il faut faire ce qui est dit dans les cours et tutoriels pour apprendre Python.

    C'est à dire qu'il faut créer un fichier nommé sitecustomize.py dans le répertoire des librairies de python (par défaut C:\Python25\Lib).
    Dans ce fichier il faut mettre ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/env python
    # -*- coding: iso-8859-1 -*-
     
    # Recuperation de la 'locale' par default.
    import locale, sys
    loc = locale.getdefaultlocale()
    if loc[1]:
        encoding = loc[1]
     
    # une version Non-Unicode retournera AttributeError...
    if encoding:
        sys.setdefaultencoding(encoding)
    Je ne comprends pas vraiment ce code mais ça marche et dans le coup le traitement des mes chaines fonctionne dans mon code aussi !!!

    Donc voilà c'est bon à savoir !

    Merci Guigui_ pour ton aide !

    @+

    ffets

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    à tous,

    Mauvaise nouvelle. Une fois le développement terminé, je créé un executable grâce à py2exe. Le problème c'est que je ne pense pas que py2exe ajoute tout l'interpréteur pythonwin quand il génère l'executable...

    Donc pour en revenir à mon souci, en fichier python mon problème d'accent est résolu tant que je reste avec des scripts en ".py" mais revient à grand pas dès que je passe en programme ".exe".

    J'ai cherché hier soir à régler ce problème d'unicode mais en vain pour le moment.
    Je continue de creuser donc si quelqu'un à une idée de comment je peux lire des caractères accentués je suis preneur !


    merki !

    A+
    ffets

  8. #8
    Membre habitué
    Inscrit en
    Novembre 2007
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 129
    Points : 160
    Points
    160
    Par défaut
    une autre solution serait de remplacer les String suceptible de contenir des caracteres exotiques par de l'unicode



    unicode( [object[, encoding [, errors]]])

    Return the Unicode string version of object using one of the following modes:
    If encoding and/or errors are given, unicode() will decode the object which can either be an 8-bit string or a character buffer using the codec for encoding. The encoding parameter is a string giving the name of an encoding; if the encoding is not known, LookupError is raised. Error handling is done according to errors; this specifies the treatment of characters which are invalid in the input encoding. If errors is 'strict' (the default), a ValueError is raised on errors, while a value of 'ignore' causes errors to be silently ignored, and a value of 'replace' causes the official Unicode replacement character, U+FFFD, to be used to replace input characters which cannot be decoded. See also the codecs module.

    If no optional parameters are given, unicode() will mimic the behaviour of str() except that it returns Unicode strings instead of 8-bit strings. More precisely, if object is a Unicode string or subclass it will return that Unicode string without any additional decoding applied.

    For objects which provide a __unicode__() method, it will call this method without arguments to create a Unicode string. For all other objects, the 8-bit string version or representation is requested and then converted to a Unicode string using the codec for the default encoding in 'strict' mode.

    New in version 2.0. Changed in version 2.2: Support for __unicode__() added.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Merci je vais jeter un oeil de ce côté quand j'aurai un peu de temps.

    @+
    ffets

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Bonjour à tous,

    J'ai testé avec l'unicode comme me l'a préconisé azalsup mais j'ai toujours un souci.

    J'arrive bien à lire et à convertir le contenu de mon fichier Excel avec de l'unicode mais au moment où je veux écrire ma chaîne dans un fichier texte j'ai ce message qui surgit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Traceback (most recent call last):
      File "C:\user\U201645\05-Travail_hors_dv6c\xls_xml\xls_avec_accents\Lecture_accents_dans_xls.py", line 35, in <module>
        ficrap.write('\t'+donnees_lues[i][j])
    UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 7: ordinal not in range(128)
    Voici le code python :
    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
    donnees_lues = sht.Range(sht.Cells(1, 1), sht.Cells(maxline, maxcol)).Value
    donnees_lues = list(donnees_lues)
     
    ficrap = open('megatest.txt', 'w')
     
    #donnees_lues est une matrice de type "tuple" de "tuple"
    #Pour faciliter le traitement par la suite on la convertit en matrice de "list" de "list"
    #Pour finir on convertit chaque case de la matrice en chaîne de caractère
    for i in range(len(donnees_lues)):
        donnees_lues[i]=list(donnees_lues[i])
        j = 0
        while j < len(donnees_lues[i]):
            print 'i = '+str(i)+'  et j = '+str(j)
            print 'Avant unicode : '+donnees_lues[i][j]
            donnees_lues[i][j]=unicode(donnees_lues[i][j])
            print 'Apres unicode : '+donnees_lues[i][j]
            ficrap.write('\t'+donnees_lues[i][j])
            j = j + 1
        ficrap.write('\n')
    Y a-t-il quelque chose que je ne fais pas comme il faut ?

    Merci !

  11. #11
    Membre habitué
    Inscrit en
    Novembre 2007
    Messages
    129
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 129
    Points : 160
    Points
    160
    Par défaut
    voici comment ouvrir ton fichier

    monfichier = codecs.open('test', encoding='utf-8', mode='w+')

    apres tu peu ecrire en unicode : http://www.amk.ca/python/howto/unicode

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Ceci à l'air de fonctionner. Merci. Je vais continuer mes essais.

    Bonnes fêtes de fin d'année à tous.
    Merci

    A+
    ffets.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 25
    Points : 24
    Points
    24
    Par défaut
    Ne pas oublier le :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # -*- coding: iso-8859-1 -*-
    en début de fichier

Discussions similaires

  1. Faire le cast d'une collection List<char> en List<int>
    Par Xx_raaY dans le forum Windows Forms
    Réponses: 4
    Dernier message: 27/07/2009, 14h08
  2. [HTML] faire des tabulation dans une liste <select>
    Par renofx1 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 20/01/2006, 23h36
  3. Réponses: 12
    Dernier message: 31/12/2005, 16h01
  4. comment faire un cast d'un CString en int ?
    Par 180degrés dans le forum MFC
    Réponses: 1
    Dernier message: 23/12/2005, 22h02
  5. Selectionnet tous ou faire un clear sur une liste
    Par Canou dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 17/11/2004, 10h26

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