如何在Python doctest结果字符串中包含特殊字符(制表符、换行符)?

22 投票
6 回答
28219 浏览
提问于 2025-04-17 10:05

给定以下的Python脚本:

# dedupe.py
import re

def dedupe_whitespace(s,spacechars='\t '):
    """Merge repeated whitespace characters.
    Example:
    >>> dedupe_whitespace(r"Green\t\tGround")  # doctest: +REPORT_NDIFF
    'Green\tGround'
    """
    for w in spacechars:
        s = re.sub(r"("+w+"+)", w, s)
    return s

这个函数在Python解释器中正常工作:

$ python
>>> import dedupe
>>> dedupe.dedupe_whitespace('Purple\t\tHaze')
'Purple\tHaze'
>>> print dedupe.dedupe_whitespace('Blue\t\tSky')
Blue    Sky

但是,doctest示例失败了,因为在与结果字符串进行比较之前,制表符会被转换为空格:

>>> import doctest, dedupe
>>> doctest.testmod(dedupe)

结果是

Failed example:
    dedupe_whitespace(r"Green           Ground")  #doctest: +REPORT_NDIFF
Differences (ndiff with -expected +actual):
    - 'Green  Ground'
    ?       -
    + 'Green Ground'

我该如何在doctest的多行字符串中正确编码制表符,以便进行合适的测试结果比较呢?

6 个回答

3

简而言之:要用两个反斜杠来表示一个反斜杠,也就是说,在你的字符串中用 \\n\\t 来代替 \n\t

你可能不想把你的文档字符串设置为原始字符串,因为那样你就无法使用任何Python字符串中的转义字符,包括你可能需要的那些。

对于支持正常转义的函数,只需在反斜杠的转义中再加一个反斜杠,这样Python解释后,就会留下一个字面意义上的反斜杠,后面跟着一个字符,这样 doctest 就能解析了。

13

这里提到的是一种叫做原始 heredoc 字符串的写法(r"""),正是这个让事情变得简单了:

# filename: dedupe.py
import re,doctest
def dedupe_whitespace(s,spacechars='\t '):
    r"""Merge repeated whitespace characters.
    Example:
    >>> dedupe_whitespace('Black\t\tGround')  #doctest: +REPORT_NDIFF
    'Black\tGround'
    """
    for w in spacechars:
        s = re.sub(r"("+w+"+)", w, s)
    return s

if __name__ == "__main__":
    doctest.testmod()
17

我用字面字符串的写法让这个功能正常运作了,具体的代码如下:

def join_with_tab(iterable):
    r"""
    >>> join_with_tab(['1', '2'])
    '1\t2'
    """

    return '\t'.join(iterable)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

撰写回答