20

我正在处理一些必须操作 unicode 字符串的代码。我正在尝试为它编写文档测试,但遇到了麻烦。以下是说明问题的最小示例:

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

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

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

$ python mylen.py
5

接下来,我们在其上运行 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 呢?

4

5 回答 5

20

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

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

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

这将起作用——只要测试通过。对于 Python 2.x,您需要另一个 hack 来使详细的 doctest 模式工作或在测试失败时获得正确的回溯:

if __name__ == "__main__":
    import sys
    reload(sys)
    sys.setdefaultencoding("UTF-8")
    import doctest
    doctest.testmod()

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

于 2009-11-14T15:10:33.817 回答
6

Python 2.6.6 不能很好地理解 unicode 输出,但这可以使用以下方法修复:

  • 已经描述了黑客攻击sys.setdefaultencoding("UTF-8")
  • unicode docstring(上面已经提到过,非常感谢)
  • print声明。

在我的情况下,这个文档字符串告诉测试被破坏了:

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

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

带有“错误”消息

Failed example:
    beatiful_units(('erg', 1), ('cm', -2), ('sec', -1))
Expected:
    u'erg/(cm² sec)'
Got:
    u'erg/(cm\xb2 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)
    '''
于 2011-07-10T10:35:20.500 回答
2

这似乎是 Python 中一个已知但尚未解决的问题。在此处此处查看未解决的问题。

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

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

print(mylen("áéíóú"))
于 2009-11-14T06:16:27.977 回答
1

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

于 2009-11-15T00:54:06.553 回答
1

如前所述,您需要确保您的文档字符串是 Unicode。

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

为了在 Python 2 中达到同样的效果,您需要保留coding: utf-8next ,您可以在所有文档字符串前面加上u,或者简单地添加

from __future__ import unicode_literals
于 2014-03-24T13:45:12.227 回答