如何使用Python中默认不支持的字符?

时间:2012-12-04 07:18:40

标签: python pdf unicode character

  

可能重复:
  UnicodeDecodeError, invalid continuation byte

我正在尝试在python生成的PDF中使用áô等字符。该程序使用dateutil模块(和其他几个)生成PDF日历(带图像)。日历用Latex布局。

我的目标是用法语创建日历,但法语中的月份名称数组包含似乎无法被python识别的字符。

在生成过程中,程序在命令行中打印SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xe9 in position 0: unexpected end of data

如何告诉python使用这些字符?

如果它有助于数组:

FRENCH_MONTHS = [u'NotAMonth', u'Janvier', u'Février', u'Mars', u'Avril', u'Mai', u'Juin', u'Juillet', u'Aôut', u'Septembre', u'Octobre', u'Novembre', u'Décembre']

也用过:

  • MPS到PDF转换器

2 个答案:

答案 0 :(得分:3)

您必须指定用于创建python源的源代码。通过添加source encoding declaration

来完成此操作
# coding: UTF-8

这应该是python源文件的第一行或第二行。编码具有以匹配您保存文件的编码;检查文本编辑器设置。您添加到问题中的错误消息表明编码不匹配,我怀疑您使用的是latin-1(ISO 8859-1)。

或者,使用unicode转义包含非ASCII字符; u'\u00e9'表示带有重音坟墓的e作为unicode代码点。

请研究Python如何在Python Unicode HOWTO中处理Unicode。对于任何处理任何非ASCII数据的软件开发人员,Joel Spolsky Unicode article也是必要的读数。

答案 1 :(得分:2)

如果你的编辑器设置为使用正确的编码保存文件,你可以使用# coding: UTF-8

或者,您也可以将字符编码为仅ASCII转义序列。例如,escape-sequence for é\u00E9

FRENCH_MONTHS = [u'NotAMonth', u'Janvier', u'F\u00E9vrier', ...]

这不太可能被配置错误的编辑器弄乱,但实现完全相同的事情。

更好的是,您可以使用calendar模块并回避整个问题(基于this answer):

import calendar


def get_month_names(locale):
    with calendar.TimeEncoding(locale) as encoding:
        months = list(calendar.month_name)

        # Could do this to match original values:
        # months = [x.title() for x in months]

        if encoding is not None:
            months = [x.decode(encoding) for x in months]

        months[0] = u"NotAMonth"
        return months

FRENCH_MONTHS = get_month_names("fr_FR.UTF-8")

编辑:这与this question的问题相同 - 您的é使用latin 1编码,但您的Python源文件编码是UTF-8(在Python 2中显式设置,或者因为它是Python 3)中的默认值:

>>> print "\xe9".decode("latin1")
é
>>> print "\xe9".decode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 0: unexpected end of data

使用上述替代解决方案的另一个好理由!