Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force repr() to use single quotes

I have a question, is there a way to "force" repr() to create always single quotes around a string?

This happens when I only use repr()

print repr("test")
'test'
print repr("test'")
"test'"
print repr("test\"")
'test"'
print repr("test'\"")
'test\'"'

so the last one actually does, what I want, but I don't want to add always \\" to get the single quotes.


Edit: I am not going to mark an answer as accepted since, as pointed out by @martijn-pieters, I was using repr() for purposes it is not intended for.

like image 665
Marcono1234 Avatar asked Dec 10 '14 13:12

Marcono1234


2 Answers

Well, if your object is always a string you could do this:

def repr_single(s):
    return "'" + repr('"' + s)[2:]

print repr_single("test'")
'test\''

But as Martijn Pieters asked I'm curious as to your use case here.

like image 96
stdout Avatar answered Oct 27 '22 19:10

stdout


I needed to do something similar once, except I wanted it to always "prefer" to use double quotes — meaning use them unless there were more of them in string than single quotes (in order to minimize the number of them that would require escaping).

The way I did this was to subclass the built-in str class and override its __repr__() method. You could probably easily reverse the logic in it to do the opposite (as well as force the character used to always be one or the other).

FWIW, here's the code:

# -*- coding: iso-8859-1 -*-

# Special string subclass to override the default
# representation method. Main purpose is to
# prefer using double quotes and avoid hex
# representation on chars with an ord() > 128
class MsgStr(str):
    def __repr__(self):
        # use double quotes unless there are more of them in the string than
        # single quotes
        quotechar = '"' if self.count("'") >= self.count('"') else "'"
        rep = [quotechar]
        for ch in self:
            # control char?
            if ord(ch) < ord(' '):
                # remove the single quotes around the escaped representation
                rep += repr(str(ch)).strip("'")
            # does embedded quote match quotechar being used?
            elif ch == quotechar:
                rep += "\\"
                rep += ch
            # else just use others as they are
            else:
                rep += ch
        rep += quotechar

        return "".join(rep)

if __name__ == "__main__":
    s1 = '\tWürttemberg'
    s2 = MsgStr(s1)
    print "str    s1:", s1
    print "MsgStr s2:", s2
    print "--only the next two should differ--"
    print "repr(s1):", repr(s1), "# uses built-in string 'repr'"
    print "repr(s2):", repr(s2), "# uses custom MsgStr 'repr'"
    print "str(s1):", str(s1)
    print "str(s2):", str(s2)
    print "repr(str(s1)):", repr(str(s1))
    print "repr(str(s2)):", repr(str(s2))
    print "MsgStr(repr(MsgStr('\tWürttemberg'))):", MsgStr(repr(MsgStr('\tWürttemberg')))
    assert eval(MsgStr(repr(MsgStr('\tWürttemberg')))) == MsgStr('\tWürttemberg')

Output:

str    s1:  Württemberg
MsgStr s2:  Württemberg
--only the next two should differ--
repr(s1): '\tW\xfcrttemberg' # uses built-in string 'repr'
repr(s2): "\tWürttemberg" # uses custom MsgStr 'repr'
str(s1):    Württemberg
str(s2):    Württemberg
repr(str(s1)): '\tW\xfcrttemberg'
repr(str(s2)): '\tW\xfcrttemberg'
MsgStr(repr(MsgStr('    Württemberg'))): "\tWürttemberg"
like image 2
martineau Avatar answered Oct 27 '22 17:10

martineau