2013-02-26 8 views
33

Ich mache einige Skripte in Python. Ich erstelle eine Zeichenfolge, die ich in einer Datei speichern. Diese Zeichenfolge enthält viele Daten, die aus der Baumstruktur und den Dateinamen eines Verzeichnisses stammen. Laut Convmv ist alle meine Arboreszenz in UTF-8.Python-Codierung utf-8

Ich möchte alles in UTF-8 behalten, weil ich es in MySQL nach speichern werde. Für jetzt, in MySQL, die in UTF-8 ist, habe ich ein Problem mit einigen Zeichen (wie é oder è - ich bin Französisch).

Ich möchte, dass Python immer Zeichenfolge als UTF-8 verwenden. Ich habe einige Informationen im Internet gelesen und das hat mir gefallen.

Mein Skript beginnt mit diesem:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 
def createIndex(): 
    import codecs 
    toUtf8=codecs.getencoder('UTF8') 
    #lot of operations & building indexSTR the string who matter 
    findex=open('config/index/music_vibration_'+date+'.index','a') 
    findex.write(codecs.BOM_UTF8) 
    findex.write(toUtf8(indexSTR)) #this bugs! 

Und wenn ich ausführen, hier ist die Antwort: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2171: ordinal not in range(128)

Edit: Ich sehe in meiner Datei, ist der Akzent schön geschrieben. Nachdem ich diese Datei erstellt habe, lese ich sie und schreibe sie in MySQL. Aber ich verstehe nicht warum, aber ich habe ein Problem mit der Codierung. Meine MySQL-Datenbank ist in UTF8 oder scheint SQL-Abfrage SHOW variables LIKE 'char%' gibt mir nur UTF8 oder Binär.

Meine Funktion sieht wie folgt aus:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

def saveIndex(index,date): 
    import MySQLdb as mdb 
    import codecs 

    sql = mdb.connect('localhost','admin','*******','music_vibration') 
    sql.charset="utf8" 
    findex=open('config/index/'+index,'r') 
    lines=findex.readlines() 
    for line in lines: 
     if line.find('#artiste') != -1: 
      artiste=line.split('[:::]') 
      artiste=artiste[1].replace('\n','') 

      c=sql.cursor() 
      c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom="'+artiste+'"') 
      nbr=c.fetchone() 
      if nbr[0]==0: 
       c=sql.cursor() 
       iArt+=1 
       c.execute('INSERT INTO artistes(nom,status,path) VALUES("'+artiste+'",99,"'+artiste+'/")'.encode('utf8') 

Und artiste, die in der Datei schön angezeigt schreibt schlecht in die BDD. Was ist das Problem?

+0

Ihr Python-Beispielcode ist ungültig. An mindestens 2 Stellen liegen Syntaxfehler vor. Können Sie das bitte zuerst beheben? –

+0

Speichern Sie die Datei als utf-8 und nicht als ASCII-Datei? – QuentinUK

Antwort

45

Sie müssen keine Daten kodieren, die bereits codiert sind. Wenn Sie das versuchen, versucht Python zuerst, es zu unicode zu dekodieren, bevor es es zurück zu UTF-8 kodieren kann. Das ist, was hier versagt:

>>> data = u'\u00c3'   # Unicode data 
>>> data = data.encode('utf8') # encoded to UTF-8 
>>> data 
'\xc3\x83' 
>>> data.encode('utf8')   # Try to *re*-encode it 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128) 

einfach Ihre Daten direkt in die Datei schreiben, gibt es keine Notwendigkeit bereits codierte Daten zu codieren.

Wenn Sie stattdessen unicode Werte stattdessen erstellen, müssten Sie tatsächlich diejenigen codieren, die in eine Datei geschrieben werden können. Sie möchten stattdessen codecs.open() verwenden, das ein Dateiobjekt zurückgibt, das Unicode-Werte für Sie in UTF-8 codiert.

Sie auch wirklich wollen nicht den UTF-8 BOM schreiben, es sei denn, Sie Microsoft-Tools zu unterstützen, die nicht UTF-8 ansonsten (wie MS Editor) lesen können.

Für Ihre MySQL Insert Problem, müssen Sie zwei Dinge tun:

  • charset='utf8' zu Ihrem MySQLdb.connect() Anruf hinzufügen.

  • Verwenden unicode Objekte, nicht str Objekte bei der Abfrage oder Einfügen, aber SQL-Parameter verwenden so der MySQL-Anschluss kann für Sie das Richtige tun:

    artiste = artiste.decode('utf8') # it is already UTF8, decode to unicode 
    
    c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,)) 
    
    # ... 
    
    c.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/')) 
    

Es kann tatsächlich besser funktionieren wenn Sie codecs.open() verwenden, um den Inhalt stattdessen automatisch zu decodieren:

Sie möchten vielleicht Unicode und UTF-8 und Kodierungen auffrischen. Ich kann die folgenden Artikel empfehlen:

+0

Können Sie meine Bearbeitung PLZ sehen? Ich bin so verloren ... – vekah

+4

@vekah: Hast du die Anweisungen in [Writing UTF-8 String zu MySQL mit Python] (http://stackoverflow.com/q/6202726) –