小编典典

python编码utf-8

python

我正在用python做一些脚本。我创建一个保存在文件中的字符串。这个字符串有很多数据,来自目录的树状结构和文件名。根据convmv的介绍,我所有的树状结构都是UTF-8。

我想将所有内容都保留在UTF-8中,因为之后我将其保存在MySQL中。现在,在UTF-8的MySQL中,我遇到了一些字符问题(例如é或è-我是法语)。

我希望python始终将字符串用作UTF-8。我在互联网上阅读了一些信息,我确实这样做。

我的脚本以此开头:

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

很好地显示在文件中的Artiste会将错误写入BDD。问题是什么 ?


阅读 214

收藏
2020-12-20

共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 BOM, 除非必须 支持否则无法读取UTF-8的Microsoft工具(例如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&(-@F','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和编码。我可以推荐以下文章:

2020-12-20