13

我经常使用 mako 得到这个错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 6: ordinal not in range(128)

我已经告诉 mako 我正在以任何可能的方式使用 unicode:

    mylookup = TemplateLookup(
        directories=['plugins/stl/templates'],
        input_encoding='utf-8',
        output_encoding='utf-8',
        default_filters=['decode.utf8'],
        encoding_errors='replace')

    self.template = Template(self.getTemplate(), lookup=mylookup,
        module_directory=tempfile.gettempdir(),
        input_encoding='utf-8',
        output_encoding='utf-8',
        default_filters=['decode.utf8'],
        encoding_errors='replace')

    html = self.template.render_unicode(data=self.stuff)

我所有的模板文件都以:

## -*- coding: utf-8 -*-

并且,在它们内部,所有常数字符串都以“u”为前缀。我知道 self.stuff 参数包含 unicode 字符串,但我实例化 mako 对象的方式应该处理它(否则这些参数有什么用?)。有什么我忘了做的吗?

还有一个问题: encoding_errors='replace' 有什么意义?

=EDIT= 我只留下了一个 unicode 字符串,这是回溯:

Traceback (most recent call last):
  File "C:\My Dropbox\src\flucso\src\plugins\stl\main.py", line 240, in updateView
    flags=self.makoflags)
  File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\template.py", line 198, in render_unicode
    as_unicode=True)
  File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 403, in _render
    _render_context(template, callable_, context, *args, **_kwargs_for_callable(callable_, data))
  File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 434, in _render_context
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
  File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 457, in _exec_template
    callable_(context, *args, **kwargs)
  File "memory:0x41317f0", line 89, in render_body
  File "C:\Python26\lib\site-packages\mako-0.3.4-py2.6.egg\mako\runtime.py", line 278, in <lambda>
    return lambda *args, **kwargs:callable_(self.context, *args, **kwargs)
  File "FriendFeed_mako", line 49, in render_inlist_entry
  File "C:\Python26\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u263c' in position 8: ordinal not in range(128)
4

3 回答 3

14

最后我把我的模板保存在 unicode 中,实际上(我猜)是 utf-16 而不是 utf-8。它们在磁盘上的大小翻了一番,mako 开始抱怨“CompileException(”Unicode decode operation of encoding 'utf-8' bla bla”,所以我将它们的第一行更改为:

## -*- coding: utf-16 -*-

删除了所有“.decode('utf-8')” - 常量字符串仍以“u”为前缀。

python中的初始化现在是:

mylookup = TemplateLookup(
    directories=['plugins/stl/templates'],
    input_encoding='utf-16',
    output_encoding='utf-16',
    encoding_errors='replace')

self.template = Template(self.getTemplate(), lookup=mylookup,
    module_directory=tempfile.gettempdir(),
    input_encoding='utf-16',
    output_encoding='utf-16',
    encoding_errors='replace')

现在可以了。看起来 utf-8 是错误的选择(或者我无法将模板保存在 utf-8 中),但我无法解释为什么它在 eclipse/pydev 中起作用。

于 2010-07-27T11:15:35.257 回答
2

为了谷歌人:

mako.exceptions.CompileException: Unicode decode operation of encoding 'ascii' failed in file当您的模板文件包含非 ascii 字符并且未将 Unicode BOM 写入文件时,Mako 会引发异常等。您需要手动添加 BOM(至少在我的文本编辑器中不会自动添加),以便:

$file test.htm
test.htm: HTML document, UTF-8 Unicode text

变成这样:

$file test.htm
test.htm: HTML document, UTF-8 Unicode (with BOM) text
于 2013-05-21T11:24:26.773 回答
0

这些建议(包括接受的答案)在所有情况下都不起作用,特别是在 mako 模板呈现内容(例如 ${value | n})的情况下,其中的值包含非 ascii 字符。

这是因为默认情况下 mako 将 unicode(foo) 包装在生成的编译模板中的任何值周围,这仍然会导致:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)

在 python2 中使 mako 处理 unicode 的唯一可靠方法是替换默认的 ('unicode') 处理程序,如下所示:

def handle_unicode(value):
    if isinstance(value, basestring):
        return unicode(value.decode('ascii', errors='ignore'))
    return unicode(value)


...    

lookup = TemplateLookup(
    directories=[self._root.template_path],
    imports=['from utils.view import handle_unicode'],
    default_filters=["handle_unicode"]
)

...

template = self._lookup.get_template(self.template())
rtn = template.render(request=self.request)
于 2014-08-11T02:42:21.707 回答