Doctest Involving Escape Characters

2019-06-17 09:39发布

问题:

Have a function fix(), as a helper function to an output function which writes strings to a text file.

def fix(line):
    """
    returns the corrected line, with all apostrophes prefixed by an escape character

    >>> fix('DOUG\'S')
    'DOUG\\\'S'

    """
    if '\'' in line:
        return line.replace('\'', '\\\'')
    return line

Turning on doctests, I get the following error:

Failed example:
    fix('DOUG'S')
Exception raised:
    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1254, in __run
        compileflags, 1) in test.globs
      File "<doctest convert.fix[0]>", line 1
        fix('DOUG'S')
                  ^

No matter what combination of \ and 's I use, the doctest doesn't seem to to want to work, even though the function itself works perfectly. Have a suspicion that it is a result of the doctest being in a block comment, but any tips to resolve this.

回答1:

Is this what you want?:

def fix(line):
    r"""
    returns the corrected line, with all apostrophes prefixed by an escape character

    >>> fix("DOUG\'S")
    "DOUG\\'S"
    >>> fix("DOUG'S") == r"DOUG\'S"
    True
    >>> fix("DOUG'S")
    "DOUG\\'S"

    """
    return line.replace("'", r"\'")

import doctest
doctest.testmod()

raw strings are your friend...



回答2:

First, this is what happens if you actually call your function in the interactive interpreter:

>>> fix("Doug's")
"Doug\\'s"

Note that you don't need to escape single quotes in double-quoted strings, and that Python does not do this in the representation of the resulting string – only the back slash gets escaped.

This means the correct docstring should be (untested!)

"""
returns the corrected line, with all apostrophes prefixed by an escape character

>>> fix("DOUG'S")
"DOUG\\\\'S"

"""

I'd use a raw string literal for this docstring to make this more readable:

r"""
returns the corrected line, with all apostrophes prefixed by an escape character

>>> fix("DOUG'S")
"DOUG\\'S"

"""