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()
I went ahead and implemented repr_double
by using
stdout's repr_single
def repr_single(s):
return "'" + repr('"' + s)[2:]
def repr_double(s):
single = repr_single(s)
return '"' + single[1:-1].replace('"', '\\"').replace('\\\'', '\'') + '"'
def test_single():
assert r"'foobar'" == repr_single('foobar')
assert r"'\'foobar'" == repr_single('\'foobar')
assert "'\\'foobar'" == repr_single("'foobar")
def test_double():
assert r'"foobar"' == repr_double("foobar")
assert '"\'foobar"' == repr_double("'foobar")
assert '"\\"foobar"' == repr_double('"foobar')
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.
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"