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 :

editer un fichier en UTF-8


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 90
    Par défaut editer un fichier en UTF-8
    Bonjour,

    j'automatise une édition de fichier XML à partir de données présente en base.

    Une fois le fichier créé, mon script lance une commande maven permettant à mon appli web de prendre en compte les données du fichier XML.

    Une fois le fichier parsé, j'ai un problème d'encodagem les "é" remplacé par "?".

    Voici ce que j'ai essayé de faire et qui ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MonFichier=open(repertoire + '/toto.xml','w')
     
    MaVar = """ du texte """
     
    MonFichier.write(MaVar .encode('UTF-8')) 
     
    MonFichier.close()
    Quand, dans notepad, je passe l'encodage du fichier en UTF-8 manuellement, mon problème est résolu.

    Merci d'avance pour votre aide !

    Manu

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut
    Tu enregistres ton fichier avec l'extension .xml, Notepad attendait sans doute la déclaration d'encodage et, à défaut, a choisit ascii.

    Si tu ajoutes cet entête à ton fichier, ça donne quoi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <?xml version="1.0" encoding="UTF-8"?>

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 90
    Par défaut
    si je rajoute cette entete, maven me jette en declarant que le mot "UTF-8" ne doit pas etre utilisé dans mon fichier.

    C'est vraiment a cause de l'encodage car si je l'encode manuellement en UTF8 et que je relance ma tache maven, tout se passe bien et mon texte est bien encodé.

    Je vais essayer comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonFichier.write(MaVar).encode('UTF-8')
    alors que je faisais comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonFichier.write(MaVar .encode('UTF-8'))
    car c'est plus le fichier qu'on encode que la variable texte.

    Je te tiens au courant.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 90
    Par défaut
    non, dans ce cas c'est une erreur

  5. #5
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Hehe, non, on encode pas un fichier, on encode un str, en python*!

    Il faut comprendre qu’un fichier est toujours, in fine, des bytes (ou octets). Quand python ouvre un fichier en mode texte, il va implicitement faire les conversions bytes→str (en lecture) ou str→bytes (en écriture), en utilisant l’encodage par défaut du système (utf-8 sous la plupart des *nix, un truc genre cp-12xx sous windaube…).

    Si on reprend ton premier exemple, pour être sûr d’enregistrer MaVar en utf-8, tu as deux solutions*:

    1) Tu précises quel encodage utiliser lors de l’ouverture du fichier en écriture*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaVar = """ du texte """
     
    with open(repertoire + '/toto.xml', 'w', encoding="utf-8") as MonFichier: 
        MonFichier.write(MaVar) 
    # pas besoin de MonFichier.close() avec with…:
    2) Tu ouvres ton fichier en mode binaire ('wb'), et tu assures toi-même l’encodage de ta str en bytes*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaVar = """ du texte """
     
    with open(repertoire + '/toto.xml', 'wb') as MonFichier: 
        MonFichier.write(MaVar.encode("utf-8")) 
    # pas besoin de MonFichier.close() avec with…:
    Attention, tout ce qui précède est en py3, py2 était encore plus pénible dans la gestion chaîne de texte/d’octets…

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 90
    Par défaut
    merci mont !

    content de t'avoir fais rire

    le script que je fais est en jython (java for python) et je crois bien que ce n'est pas compatible py3.

    La syntaxe "with open" ne marche pas.
    J'ai lancé le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    repertoire = 'C:/temp'
    MaVar = """ régle de fou ça """
     
    MonFichier = open(repertoire + '/toto.xml','wb')
    MonFichier.write(MaVar.encode("utf-8")) 
    MonFichier.close()
    Quand j'ouvre le fichier avec notepad, onglet encodage, il est en "UTF-8 sans BOM"

    et le texte est le suivant :

    On y est presque mais c'est pas encore ça

    Bon week end

  7. #7
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Eeeeeh… Si on est en py2, vaudrait peut-être mieux spécifier que la chaîne est unicode, à sa création*? Genre…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    repertoire = 'C:/temp'
    MaVar = u""" régle de fou ça """
     
    MonFichier = open(repertoire + '/toto.xml', 'wb')
    MonFichier.write(MaVar.encode("utf-8")) 
    MonFichier.close()
    … Mais je dois bien reconnaître que ne pratiquant que py3 depuis un certain temps, j’ai quelque peu perdu les réflexes de l’arthritique ancêtre…

  8. #8
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Citation Envoyé par mont29 Voir le message
    Mais je dois bien reconnaître que ne pratiquant que py3 depuis un certain temps, j’ai quelque peu perdu les réflexes de l’arthritique ancêtre…
    L'ancêtre Py2 se porte encore très bien, à côté de "l'ado" Py3 qui n'a pas encore tout (ses modules) pour devenir adulte .


    Sinon, quelques petits compléments concernant la question posée:

    - pour convertir une chaine d'un encodage non-unicode à un autre encodage non-unicode, on doit toujours passer par l'unicode. Exemple pour passer de l'utf-8 au latin1: ch.decode('utf-8').encode('latin1'). Dans cet exemple, ch.decode('utf-8') convertit l'utf-8 en unicode, et .encode('latin1') convertit l'unicode en latin1.

    - sous Py2, il plus facile de travailler en interne en unicode, et d'utiliser le module "codecs" pour lire / écrire des fichiers sur disque en précisant alors l'encodage: le module "codecs" se débrouille alors pour faire les conversions.

    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
    import codecs
     
    ch = u"éèçàùöï" # ch est en unicode grâce à 'u'
     
    f = codecs.open("monfichier.txt", 'w', 'utf-8')
    f.write(ch + '\n')
    f.close()
    # ch est en utf-8 sur disque grâce à codecs
     
    f = codecs.open("monfichier.txt", 'r', 'utf-8')
    ch2 = f.read()
    f.close()
    # ch2 est en unicode en ram grâce à codecs
     
    print ch2.encode(sys.stdout.encoding)
    éèçàùöï
    - pour savoir si une chaine a le bon encodage, il faut se méfier de l'affichage, parce que la console d'affichage a elle aussi un encodage! On trouve celui-ci avec sys.stdout.encoding, et si nécessaire, il faut faire la conversion. Par exemple, si le texte est en utf-8 => print chaine.decode("utf-8").encode(sys.stdout.encoding). Si le texte est déjà en unicode, on n'a plus besoin du "decode". A noter cependant que dans certains éditeurs intégrés aux outils de développement, sys.stdout.encoding renvoie 'None': il faut alors consulter la notice pour connaître l'encodage d'affichage de la console.

    Attention aussi lors de l'affichage, il est courant que l'affichage d'une chaine avec caractères accentués soit différent lorsqu'elle est seule ou lorsqu'elle est intégrée dans une liste. Par exemple (ici avec PyScripter):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    print u"éèçàùöï"
    éèçàùöï
    print [u"éèçàùöï"]
    [u'\xe9\xe8\xe7\xe0\xf9\xf6\xef']
    Le remède: transformer la liste en chaine pour l'affichage.

    A titre de vérification, il est intéressant de voir comment un texte dans un fichier sur disque est encodé, en utilisant un éditeur hexa (j'utilise EditHexa).

    Enfin, dans les éditeurs de texte, il faut en général que la configuration d'encodage existe lors de la création du fichier. Après modification du texte, tous les éditeurs ne permettent pas les changements d'encodage avec la conversion du texte existant. Par contre, Notepad++ le fait très bien: commande "encodage => convertir en utf-8".

    [EDIT] A noter que la lecture d'un fichier encodé en 'utf-8 avec BOM' se lit avec l'encodage Python 'utf_8_sig' et non simplement 'utf-8'.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 90
    Par défaut
    Merci infiniment !

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

Discussions similaires

  1. [C#]Edition de fichiers office dans une winform
    Par cyrille_naert dans le forum Windows Forms
    Réponses: 2
    Dernier message: 02/01/2007, 16h50
  2. Export d'une base MySQL vers un fichier texte UTF-8
    Par zian974 dans le forum Outils
    Réponses: 2
    Dernier message: 28/08/2006, 20h36
  3. [FTP] Editer des fichiers distants
    Par bigtof dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 17/08/2006, 00h28
  4. ecrire un fichier en utf-8
    Par elzedo dans le forum Langage
    Réponses: 10
    Dernier message: 09/03/2006, 22h12
  5. [XML-JSP] Editer un fichier XML
    Par sempire dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 24/08/2005, 22h24

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