Force repr() to use single quotes

五迷三道 提交于 2019-12-18 06:48:46

问题


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.


回答1:


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.




回答2:


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"



回答3:


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')


来源:https://stackoverflow.com/questions/27402168/force-repr-to-use-single-quotes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!