7
votes

Latin-1 et l'usine Unicode en python

J'ai un script Python 2.6 qui gronde sur des caractères spéciaux encodés en latin-1, que je récupère à partir d'une base de données SQL Server. J'aimerais imprimer ces personnages, mais je suis un peu limité car j'utilise une bibliothèque qui appelle l'usine code> unicode code>, et je ne sais pas comment faire python utiliser un codec autre que ASCII code>.

Le script est un outil simple pour renvoyer des données de recherche à partir d'une base de données sans avoir à exécuter le SQL directement dans un éditeur SQL. J'utilise le Prettytable 0.5 Bibliothèque pour afficher les résultats. P>

Le noyau du script est ce bit de code. Les tuples que je reçois du curseur contiennent des données entier et de chaîne, et aucune donnée Unicode. (J'utiliserais adodbapi code> au lieu de pyodbc code>, qui me ferait unicode, mais adodbapi code> me donne d'autres problèmes.) P> xxx pré>

mais la colonne nom code> peut contenir des caractères qui tombent en dehors de la gamme ASCII. Je vais parfois obtenir un message d'erreur comme celui-ci, dans la ligne 222 de pretthable.pyc code>, quand il passe au t.add_row code> appel: p>

x = pyodbc.connect(cxnstring)
r = x.cursor()
r.execute(sql)

t = PrettyTable(columns)
for rec in r:
    urec = [s.decode('latin-1') if isinstance(s, str) else s for s in rec]
    t.add_row(urec)
r.close()
x.close()

t.set_field_align("ID", 'r')
t.set_field_align("Name", 'l')
print t.get_string().encode('latin-1')


0 commentaires

3 Réponses :


7
votes

Ajoutez ceci au début du module: xxx

ou décode la chaîne à vous-même.

[modifier]

Ça a été Un certain temps depuis que j'ai joué avec unicode, mais j'espère que cet exemple montrera comment convertir de latin1 en Unicode: xxx

[modifier]

Documentation: < BR> http://docs.python.org/howto/unicode.html
http://docs.python.org/library/codecs.html


6 commentaires

J'ai essayé de mettre le codage au sommet de mes scripts, mais cela ne fonctionne toujours pas. Je vais essayer le décodage explicite, mais j'espère qu'il y a une solution plus générale.


Vous ne voulez probablement pas définir la codage: latin1. Cela modifie l'encodage de la source du script, pas ses données.


@Glenn: J'ai suggéré que parce que je pensais que imprimer t peut imprimer des chaînes brutes latin1.


Mon script n'a pas de littéraux de chaîne avec des caractères non ASCII. Donc, cela ne devrait pas être un facteur.


@Bastien Léonard: Les données que je reçoivent de la base de données ne sont pas unicode. Le caractère en question est 0xed. Je ne peux pas décoder 0xed avec le codec ASCII. Existe-t-il un moyen de modifier le codage par défaut uniquement pour cette fonction unique, de sorte que Unicode fonctionnerait?


@Bastien Léonard: J'ai une combinaison qui a finalement travaillé. Je vais le classer jusqu'à la fin de ma question. Merci pour l'aide.



2
votes

Peut-être essayez peut-être de décoder les chaînes codées latin1 à UNICODE?

t.add_row((value.decode('latin1') for value in rec))


2 commentaires

t.add_row ([S.Decode ("Latin-1 ') Si IsInstance (S, STR) ailleurs S pour S en Rec]) # Je pense que vous vouliez dire ceci (ou quelque chose comme ça).


Probablement, en fonction de la nécessité de ce que cette pretthable est nécessaire.



0
votes

4 commentaires

Si elle utilise des objets Unicode en interne, il devrait y avoir un moyen d'obtenir des objets Unicode et d'éviter de les convertir inutilement. Tant que vous utilisez toujours des objets Unicode, vous évitez la plupart de ce gâchis (c'est ainsi que Python 3 fonctionne toujours).


Je crois que ça fait: "get_string".


@ elo80ka, les données sont vraiment stockées comme latin-1. J'ai vérifié cela avant d'écrire le script. Aussi (en Python 2.6 au moins), INTS ne peut pas être contraint à l'aide de Unicode (int_value, 'latin-1') , même si Unicode (int_value) fonctionne. @Glenn Maynard, imprimer les résultats implique un décodage, défini ou non explicitement. J'ai dû utiliser t.get_string (). Encode ("Latin-1 ') Ouais, j'attends avec impatience l'adoption généralisée de PY3K, de sorte que toutes les chaînes soient unicode. Cela économiserait beaucoup de tracas.


@Eksortso: Vous avez raison ... Les ensembles de caractères n'ont pas vraiment de sens pour les chiffres de toute façon.