Partage
  • Partager sur Facebook
  • Partager sur Twitter

Codage des caractères UTF-8

Sujet résolu
    19 février 2012 à 23:30:04

    Bonsoir,
    Je n'ai pas bien compris la gestion de l'encodage des caractères en python. Je voudrais dans une chaine de caractère normal, insérer le caractère UTF-8 suivant : "\xac" (la négation). Le problème, c'est que si j'insère ce code dans ma chaine de caractère, on m'affiche un point d'interrogation. Comment dois-je faire pour vouloir afficher ce caractère ? J'ai tenté d'ajouter en première ligne du fichier la ligne :
    # -*- coding: utf-8 -*-
    


    Mais ça ne change rien.
    Merci d'avance,
    Bonne soirée.
    • Partager sur Facebook
    • Partager sur Twitter
      20 février 2012 à 0:09:07

      Rajoute un u devant ta chaîne.
      print(u"Mon signe : \xac")
      


      Pour les explications, je pense dire une énorme erreur, les problèmes d'encodage, je n'y connais pas grand chose. Mais je vais tenter.

      Si mes souvenirs sont bons, les versions python inférieurs à la version 3 utilisent des strings qui ne sont pas unicode par défaut. Par contre, à partir du 3, elles le sont par défaut.

      Donc, il faut rajouter le "marqueur" u juste devant la string.
      • Partager sur Facebook
      • Partager sur Twitter
        20 février 2012 à 0:13:21

        Tu devrais préciser la version de Python que tu utilises.
        Les string en Python2 ne sont pas en Unicode par défaut.
        En Python3, les string sont en Unicode par défaut.

        Ensuite, avec Python3, il faudra préciser quel éditeur tu utilises,
        il doit être configuré pour accepter l'Unicode.

        Tu dois préciser aussi ton système d'exploitation, au cas où.
        Je peux t'aider avec Linux, pas pour les autres.

        print("3×7±1 ≠ 99")
        

        ceci passe sans problème avec Python3, avec IDLE(éditeur d'origine), ou bien d'autres, ... configurés en Utf8.

        -----

        Si tu as un problème, tu es prié de donner le code qui dérange (le tout dans les balises >>code<<), et les détails autour.
        • Partager sur Facebook
        • Partager sur Twitter
          20 février 2012 à 0:16:39

          Oui en effet. Donc je suis sous Mac OS X avec python 3. J'utilise Komodo (IDLE étant bogué sous Mac).

          Et je souhaite faire quelque chose du style :
          return '(\xac'+ str(self.expr)+')'
          


          Sauf que j'ai un "?" à la place du caractère '\xac' .
          • Partager sur Facebook
          • Partager sur Twitter
            20 février 2012 à 0:18:50

            Ça fonctionne bien chez moi, ça affiche ¬. Tu dis que tu as un point d'interrogation, mais où ? Dans la console ?

            C'est peut-être celle-ci qui gère mal l'UTF-8.
            • Partager sur Facebook
            • Partager sur Twitter
              20 février 2012 à 0:25:55

              Oui dans la console. Bon je vais tenter de regarder ça, merci ;) .
              • Partager sur Facebook
              • Partager sur Twitter
                20 février 2012 à 12:54:57

                Ou bien c'est l'encodage de la console qui n'est pas en UTF-8, ou bien c'est la font choisie pour cette dernière qui n'a pas été prévue pour afficher ce caractère.
                • Partager sur Facebook
                • Partager sur Twitter
                  20 février 2012 à 14:23:19

                  La console est en UTF-8, et j'ai changé la police de caractère en time new roman, mais toujours ce point d'interrogation;
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 février 2012 à 14:45:56

                    si tu a accès à un viewer de tous les caractères d'une fonte (équivalent de la table des caractères sous windows), tu peux vérifier si les caractères concernés pour la police donnée sont bien présents. Ensuite, malheureusement je ne saurais t'aider d'avantage cause je ne connais pas mac, je ne sais donc absolument pas comment il gère l'unicode et les encodages... car rappelons-le unicode n'est pas un encodage.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      25 février 2012 à 11:09:13

                      Fais un "print repr( ta chaine )", cela doit afficher u'\xac'. Si c'est le cas, python a la bonne donnée et c'est un problème d'affichage dans la console.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        28 février 2012 à 12:18:38

                        Je up, car je pense que mon problème est aileurs, sans donner mon code source un poil compliqué je vais essayer de simplifié mon problème :
                        # -*- coding:utf-8 -*-
                        class B:
                            #blabla
                            def __str__(self):
                                return '('+str(trucClasseA)+')'
                            
                        class A(B):
                            #blabla
                            def __str__(self):
                                return u'(\xac'+str('truc')
                        


                        Et j'ai une erreur :
                        return unicode('('+str(self.expr1)+ ' /\ ' +str(self.expr2)+')')
                        UnicodeEncodeError: 'ascii' codec can't encode character u'\xac' in position 1: ordinal not in range(128)
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          28 février 2012 à 12:30:47

                          Pour commencer, ton code n'est pas fonctionnel, si tu veux bien le modifier pour faciliter les tests, ça serait cool.

                          Chez moi ça fonctionne sans utiliser unicode, d'ailleurs en python3 il ne devrait plus y avoir de problème

                          return '\xac'+"truc"
                          


                          Je ne vois pas où pourrait être le bug.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            29 février 2012 à 13:56:13

                            ok... il faut bien comprendre la difference entre unicode et un encodage... bienvenue dans le casse-tête des caractères :)

                            Un peu d'histoire pour commencer, au debut des ordinateur comme on les connait aujourd'hui (écran, clavier), dans un fichier texte, chaque caractères était représenter par un octet, cela laissait en tout 255 possibilités, les caractères de la langue anglaise (sans accent donc) plus quelques caractères spéciaux (retour chariot, linebreak, bip, etc...) tenaient sur les 120 premières valeurs, c'est le code ascii, il est universel quelque soit l'encodage choisi puisque c'est toujours les 120 premières valeurs d'un encodage. Puis différents pays ayant besoin de différents caractères supplémentaires, chacun a créer son propre encodage en se servant des autres valeur libres... ce qui à eu pour effet que la valeur d'un caractère dans un encodage pour le grec par exemple, pourrait être utilisée pour représenter un autre caractère dans l'encodage russe. Sans parler des langues asiatiques qui ont besoin de deux (voir quatre selon la richesse de la langue) octets pour représenter un caractère. Inutile de préciser qu'en plus de cela beacoup d'encodage au sein d'un même pays pour une même langues virent le jour, l'informatique n'ayant alors pas d'organisme officiel chargé de gérer et créer un/des standards.

                            Unicode est une table de symboles "globale", cad que tous les caractère existant au monde ont un code unicode unique, mais ce n'est pas un encodage, cad qu'il n'a pas de représentation binaire écrite associée, il ne peut être écrit sur le disque dur.

                            en python, puisque tu as python 3, les chaines sont gérées en unicode, mais à chaque fois qu'elle sont écrite sur le disque ou quelle doivent être afficher dans une console système, sont encoder dans un encodage, encodage qui diffère selon le pays et/ou le contexte d'exécution du code. un caractère unicode au sein d'un string commence par '\u' suivi de quatres valeur hexadecimales, par exemple :
                            >>> '\u00c8'
                            'È'
                            >>> '\u00c8'.encode('utf8') #le même caractère sous sa forme hexadécimale (binaire au final) en utf8
                            b'\xc3\x88'
                            >>> '\u00c8'.encode('cp1252') #en cp1252 (latin-1)
                            b'\xc8'
                            >>>
                            


                            La valeur hexa d'un octet au sein d'une chaîne est représentée par '\x'+deux valeurs hexa, tu remarquera alors que l'utf8 est un encodage à deux octets. D'ailleurs, reflexion personelle : je n'ai jamais vraiment compris pourquoi le 8 d'utf8 puisque c'est encodé sur 16 bits, et utf16 sur 32...

                            ton erreur donc, tu devrais avoir compris, vient du fait que tu écrive
                            u'\xac'
                            

                            >>> '\xac' #python fait une convertion auto  encodage locale->unicode
                            '¬'
                            >>> u'\xac' #python traite directement la chaine comme unicode, or, \x[hexa,hexa] est une forme encodee !
                            SyntaxError: invalid syntax
                            


                            Attention !

                            la ligne
                            # -*- coding:utf-8 -*-
                            

                            ne sert que d'indication à python sur l'encodage du fichier (puisque cette ligne n'utilise que des caractères ascii, elle sera toujours reconnue), elle n'a aucun impact sur l'interprétation des strings. C'est comme préciser la langue d'un article, cet article pouvant parler d'une autre langue.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              29 février 2012 à 14:22:47

                              Citation

                              je n'ai jamais vraiment compris pourquoi le 8 d'utf8 puisque c'est encodé sur 16 bits, et utf16 sur 32...


                              En fait en utf-8 les caractères sont encodés sur 1 à 4 "morceau de 8 bits" alors qu'utf-16 les caractères sont encodés sur 1 à 2 "morceau de 16 bits", enfin en utf-32 ils sont encodés sur un seul "morceau" de 32 bits.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                29 février 2012 à 14:35:12

                                ok... merci :), on en apprends tous les jours. Dinc si je comprends bien, des trois utf, l'utf-8 est celui qui demande la plus grande complexité d'interprétation, c'est bien ça ?
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  29 février 2012 à 17:13:16

                                  J'aurai plutôt dit que l'utf-32 est le plus simple (parce que utf-8 et utf-16 nécessitent tous les deux une sorte de "parsing").
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    29 février 2012 à 21:38:55

                                    Je donne des nouvelles. Donc au final, si la console m'affiche un point d'interrogation, ça viendrait donc de la console ? Pourtant l'encodage des caractères se fait bien en utf-8 ... Je comprend pas !
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      29 février 2012 à 22:00:16

                                      hmmm... python possède un encodage local qui n'est pas forcément le même que celui utilisé par ton système (mac os)... d'où, je dirais, le fait que tu te retrouve avec des "?" sans pour autant lever d'erreur python.

                                      Par exemple, voici un moyen de connaitre les deux :
                                      >>> import sys
                                      >>> sys.getdefaultencoding()
                                      'utf-8'
                                      >>> sys.getfilesystemencoding()
                                      'mbcs'
                                      >>> '\u00c8'.encode('mbcs')
                                      b'\xc8'
                                      >>> '\u00c8'.encode('utf-8')
                                      b'\xc3\x88'
                                      >>> '\u00c8'
                                      'È'
                                      


                                      petite question, ton programme tu l'execute en live depuis la console interactive python ? Depuis une console systeme ? C'est une appli avec interface graphique ?
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        29 février 2012 à 22:37:57

                                        Je l'éxécute en live depuis la console système.

                                        Edit : J'ai :
                                        >>> import sys
                                        >>> sys.getdefaultencoding()
                                        'ascii'
                                        >>> sys.getfilesystemencoding()
                                        'utf-8'
                                        


                                        OK :
                                        >>> import sys
                                        >>> sys.version_info
                                        (2, 6, 1, 'final', 0)
                                        


                                        Ce qui me surprend car j'ai les version 3.1 et 3.2 d'installées...
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Anonyme
                                          29 février 2012 à 22:50:03

                                          Du ASCII en interne, c'est Python 2, non ?

                                          Tu ne lance pas le bon Python : dans un terminal, tape python3.2.

                                          PS: Surtout ne pas supprimer Python 2 ! Il est indispensable pour d'autre programme.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Anonyme
                                            29 février 2012 à 22:52:29

                                            Pour avoir l'interpréteur de la version 3

                                            python3
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              29 février 2012 à 22:56:59

                                              Je suppose que mac OS, a l4instar de son cousin lointain linux possède par défaut une version de python installée, et que pour des raison de stabilité du système, c'est vers cette dernière que la commande python pointe.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                29 février 2012 à 22:57:22

                                                Oui, après une recherche sur internet, je viens de voir... Désolé pour les emmerdements, et merci à vous tous d'avoir pris la patience de me répondre ;)
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Codage des caractères UTF-8

                                                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                • Editeur
                                                • Markdown