Подтвердить что ты не робот

Кодирование python utf-8

Я делаю несколько скриптов в python. Я создаю строку, которую я сохраняю в файле. В этой строке было много данных, поступающих из арсенала и имен файлов каталога. Согласно convmv, все мои arborescence находятся в UTF-8.

Я хочу сохранить все в UTF-8, потому что я сохраню его в MySQL после. Пока что в MySQL, который находится в UTF-8, у меня возникла проблема с некоторыми символами (например, é или è - I'am French).

Я хочу, чтобы python всегда использовал строку как UTF-8. Я прочитал некоторую информацию в Интернете, и мне это понравилось.

My script начните с этого:

 #!/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!

И когда я выполняю, вот ответ: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2171: ordinal not in range(128)

Изменить: Я вижу, что в моем файле акцент хорошо написан. После создания этого файла я прочитал его, и я напишу его в MySQL. Но я не понимаю, почему, но у меня проблемы с кодировкой. Моя база данных MySQL находится в utf8 или кажется SQL-запросом SHOW variables LIKE 'char%' возвращает мне только utf8 или двоичный файл.

Моя функция выглядит так:

#!/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')

И артист, который хорошо отображается в файле, плохо записывается в BDD. В чем проблема?

4b9b3361

Ответ 1

Вам не нужно кодировать данные, которые уже закодированы. Когда вы попытаетесь это сделать, Python сначала попытается декодировать его до unicode, прежде чем он сможет закодировать его обратно в UTF-8. Вот что здесь не получается:

>>> 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)

Просто напишите ваши данные непосредственно в файл, нет необходимости кодировать уже закодированные данные.

Если вместо этого вы создадите значения unicode, вам действительно нужно будет закодировать их для записи в файл. Вместо этого вы хотите использовать codecs.open(), который возвращает объект файла, который будет кодировать значения Unicode для UTF-8 для вас.

Вы также действительно не хотите записывать спецификацию UTF-8, если только вы не должны поддерживать инструменты Microsoft, которые не могут читать UTF-8 в противном случае (например, MS Notepad).

Для вашей проблемы с вставкой MySQL вам нужно сделать две вещи:

  • Добавьте charset='utf8' к вашему вызову MySQLdb.connect().

  • Используйте объекты unicode, а не объекты str при запросе или вставке, но используйте параметры sql, чтобы соединитель MySQL мог сделать для вас правильные вещи:

    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'/'))
    

Он может работать лучше, если вы использовали codecs.open() для автоматического декодирования содержимого:

import codecs

sql = mdb.connect('localhost','admin','ugo&([email protected]','music_vibration', charset='utf8')

with codecs.open('config/index/'+index, 'r', 'utf8') as findex:
    for line in findex:
        if u'#artiste' not in line:
            continue

        artiste=line.split(u'[:::]')[1].strip()

    cursor = sql.cursor()
    cursor.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,))
    if not cursor.fetchone()[0]:
        cursor = sql.cursor()
        cursor.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/'))
        artists_inserted += 1

Возможно, вы захотите освежить Unicode и UTF-8 и кодировки. Я могу порекомендовать следующие статьи: