如何在Python doctests中包含unicode字符串?

如何在Python doctests中包含unicode字符串?,python,unicode,doctest,Python,Unicode,Doctest,我正在编写一些必须操作unicode字符串的代码。我正试图为它写博士论文,但我遇到了麻烦。以下是说明问题的一个简单示例: # -*- coding: utf-8 -*- def mylen(word): """ >>> mylen(u"áéíóú") 5 """ return len(word) print mylen(u"áéíóú") 首先,我们运行代码以查看print mylen(u“áêíóú”)的预期输出 接下来,我们对其运行doctest以查

我正在编写一些必须操作unicode字符串的代码。我正试图为它写博士论文,但我遇到了麻烦。以下是说明问题的一个简单示例:

# -*- coding: utf-8 -*-
def mylen(word):
  """
  >>> mylen(u"áéíóú")
  5
  """
  return len(word)

print mylen(u"áéíóú")
首先,我们运行代码以查看
print mylen(u“áêíóú”)
的预期输出

接下来,我们对其运行doctest以查看问题

$ python -m
5
**********************************************************************
File "mylen.py", line 4, in mylen.mylen
Failed example:
    mylen(u"áéíóú")
Expected:
    5
Got:
    10
**********************************************************************
1 items had failures:
   1 of   1 in mylen.mylen
***Test Failed*** 1 failures.

那么,我如何测试mylen(u“áêíóú”)的计算结果是否为5?

在Python中,这似乎是一个已知且尚未解决的问题。请参阅未解决的问题和解决方案

毫不奇怪,它可以修改为在Python 3中正常工作,因为所有字符串都是Unicode:

def mylen(word):
  """
  >>> mylen("áéíóú")
  5
  """
  return len(word)

print(mylen("áéíóú"))

如果你想要unicode字符串,你必须使用unicode文档字符串!小心
u

# -*- coding: utf-8 -*-
def mylen(word):
  u"""        <----- SEE 'u' HERE
  >>> mylen(u"áéíóú")
  5
  """
  return len(word)

print mylen(u"áéíóú")

注意!仅可出于调试目的使用setdefaultencoding。我会接受它作为doctest使用,但不会在生产代码中的任何地方使用。

我的解决方案是转义unicode字符,如u'\xe1\xe9\xed\xf3\xfa'。虽然不容易阅读,但我的测试只有几个非ASCII字符,因此在这些情况下,我将描述放在旁边作为注释,如“#n with tilde”。

Python 2.6.6不太理解unicode输出,但可以使用以下方法解决此问题:

  • 已经用
    sys.setdefaultencoding(“UTF-8”)
  • unicode文档字符串(上面也提到过,非常感谢)
  • 打印
    语句
在我的例子中,这个docstring告诉我们测试被破坏了:

def beatiful_units(*units):
    u'''Returns nice string like 'erg/(cm² sec)'.

    >>> beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
    u'erg/(cm² sec)'
    '''
带有“错误”消息

使用
print
我们可以解决以下问题:

def beatiful_units(*units):
    u'''Returns nice string like 'erg/(cm² sec)'.

    >>> print beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
    erg/(cm² sec)
    '''

如前所述,您需要确保您的docstring是Unicode

如果您可以切换到Python3,那么它将在那里自动工作,因为源编码已经是utf-8,默认字符串类型是Unicode

为了在Python2中实现同样的效果,您需要保留
编码:utf-8
,您可以在所有docstring前面加
u
,或者只需添加

from __future__ import unicode_literals

谢谢不幸的是,这种方法打破了斯芬克斯的“makedoctest”。它以一个“utf8”编解码器结束,无法解码位置…:invalid data.Hmmm中的字节。嗯,我把它用于我自己的医生考试。对不起,我不知道这是怎么回事。谢谢!不过,这种方法不适用于任何在Python2.x上自动发现测试的包。公平地说,这可能是更好的通用解决方案。然而,在我的例子中,由于对matplotlib和numpy的依赖,我仍然局限于Python2.x。
Failed example:
    beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
Expected:
    u'erg/(cm² sec)'
Got:
    u'erg/(cm\xb2 sec)'
def beatiful_units(*units):
    u'''Returns nice string like 'erg/(cm² sec)'.

    >>> print beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
    erg/(cm² sec)
    '''
from __future__ import unicode_literals