overexchange overexchange - 3 days ago 8
Python Question

Why does repr() add escape characters?

From the below

clock
decorator,

import time
from functools import wraps

DEFAULT_FMT = '[{elapsed:0.8f}s] {name}({args}) -> {result}'

def clock(fmt=DEFAULT_FMT):
def decorate(func):
@wraps(func)
def wrapper(*args):
t0 = time.time()
result = func(*args)
elapsed = time.time() - t0
name=func.__name__
args = ','.join(repr(arg) for arg in args)
result=repr(result)
print(fmt.format(**locals()))
return result
return wrapper
return decorate


result=repr(result)
is adding escape
\\\
characters in output string, for below code,

from functools import lru_cache
from clock_package import clock

emptyRecrList = None

#Representation - start
#Constructor
def list(first, rest):
return [first, rest]

def first(s):
assert s != empty, 'empty linked list has no first'
return s[0]

def rest(s):
assert s != empty, 'empty linked list has no rest'
return s[1]
#Representation - end


def fibSequence(k:int) -> list:
prev, curr = 1, 0
@lru_cache() # applied last
@clock() # applied first
def genSequence(prev, curr, k):
if k == 0:
return emptyRecrList
elif k == 1:
return list(curr, emptyRecrList)
else:
return list(curr, genSequence(curr, prev+curr, k-1))
return genSequence(prev, curr, k)

if __name__ == '__main__':
fibSequence(11)





Expected output:

$ python3.6 fibonacci.py
[0.00000167s] genSequence(34,55,1) -> [55, None]
[0.00007153s] genSequence(21,34,2) -> [34, [55, None]]
[0.00010061s] genSequence(13,21,3) -> [21, [34, [55, None]]]
[0.00012279s] genSequence(8,13,4) -> [13, [21, [34, [55, None]]]]
[0.00014472s] genSequence(5,8,5) -> [8, [13, [21, [34, [55, None]]]]]
[0.00016618s] genSequence(3,5,6) -> [5, [8, [13, [21, [34, [55, None]]]]]]
[0.00018954s] genSequence(2,3,7) -> [3, [5, [8, [13, [21, [34, [55, None]]]]]]]
[0.00021267s] genSequence(1,2,8) -> [2, [3, [5, [8, [13, [21, [34, [55, None]]]]]]]]
[0.00023627s] genSequence(1,1,9) -> [1, [2, [3, [5, [8, [13, [21, [34, [55, None]]]]]]]]]
[0.00026131s] genSequence(0,1,10) -> [1, [1, [2, [3, [5, [8, [13, [21, [34, [55, None]]]]]]]]]]
[0.00028825s] genSequence(1,0,11) -> [0, [1, [1, [2, [3, [5, [8, [13, [21, [34, [55, None]]]]]]]]]]]





Actual output is here

Why
result=repr(result)
add escape characters in the output string?

Answer Source

The issue you're having is that your clock decorator is changing the type returned by your function. I suspect you intend the line result=repr(result) to only effect the printing of the current line, but it's affecting later lines because when result gets returned, it's a string instead of a list. When it gets included in later results, the quotation marks conflict and Python starts using backslashes to escape them. Then it needs more backslashes to escape the previous ones, ending up with the mess you have shown.

Try using a different variable name for the repr'd result you print and for the unmodified result you return:

    def wrapper(*args):
        t0 = time.time()
        raw_result = func(*args)               # use a different variable name here
        elapsed = time.time() - t0
        name=func.__name__
        args = ','.join(repr(arg) for arg in args)
        result=repr(raw_result)                # convert to string for display
        print(fmt.format(**locals()))
        return raw_result                      # return the unmodified version