embed data inside string

Bengt Richter bokr at oz.net
Thu May 16 18:15:26 EDT 2002


On Thu, 16 May 2002 07:23:24 -0700, Julia Bell <julia.bell at jpl.nasa.gov> wrote:

>Thanks for all of the responses.
>
>I recognize that the formatted strings are just as simple as the example line I gave
>using the concatenation.   (I just used the simple example to demonstrate the point).
>My actual application is more complex (lots of escaped characters, combination of
>single and double quotes, etc. - just a messy string to be creating - so I was hoping
>to at least eliminate the parts of the definition that involved leaving the quoted
>portion to evaluate the parameter).
>
>But, from the responses it looks like the concatenation I'm using is probably the
>easiest way to go.
>
There are some things about strings (rhymes ;-) that can be handy.
You know about triple quotes and the r prefix that makes a r'raw string'
I assume. But you can also compose string constants variously by making
use of the fact that two strings only separated by white space get concatenated
by the compiler, and putting () around an expression allows you to spread it
over several lines ignoring indentation inside the (), e.g.,

 >>> s = (
 ... "<double quoted>\n"
 ... '<single quoted>\n'
 ... """<triple quoted
 ... -- second line of triple quote>"""
 ... r'<raw string with escape char for eol \n>'
 ... '\n<evaluated \\n in front of this makes this another line>\n'
 ... + str(1234) +
 ... "<= that was dynamically generated\n"
 ... )

The above actually compiled to s = firstpart + str(1234) + lastpart, making it
more efficient that putting plusses between everything. Proof:

 >>> dis.dis(compile(r'''\
 ... s = (
 ... "<double quoted>\n"
 ... '<single quoted>\n'
 ... """<triple quoted
 ... -- second line of triple quote>"""
 ... r'<raw string with escape char for eol \n>'
 ... '\n<evaluated \\n in front of this makes this another line>\n'
 ... + str(1234) +
 ... "<= that was dynamically generated\n"
 ... )''','','exec'))
           0 SET_LINENO               0

           3 SET_LINENO               2
[1]-->>    6 LOAD_CONST               0 ('<double quoted>\n<single quoted>\n<triple quoted\
 n-- second line of triple quote><raw string with escape char for eol \\n>\n<evaluated \\n
 in front of this makes this another line>\n')
           9 LOAD_NAME                0 (str)
          12 LOAD_CONST               1 (1234)
          15 CALL_FUNCTION            1
          18 BINARY_ADD
[2]-->>   19 LOAD_CONST               2 ('<= that was dynamically generated\n')
          22 BINARY_ADD
          23 STORE_NAME               1 (s)
          26 LOAD_CONST               3 (None)
          29 RETURN_VALUE 

[1] is the firstpart single string constant, and
[2] is the second. str(1234) comes between.

The whole string is

 >>> s
 '<double quoted>\n<single quoted>\n<triple quoted\n-- second line of triple quote><raw str
 ing with escape char for eol \\n>\n<evaluated \\n in front of this makes this another line
 >\n1234<= that was dynamically generated\n'

print uses the escape-generated characters instead of showing them as escaped:
 >>> print s
 <double quoted>
 <single quoted>
 <triple quoted
 -- second line of triple quote><raw string with escape char for eol \n>
 <evaluated \n in front of this makes this another line>
 1234<= that was dynamically generated

Of course you can use triple quoted raw strings to quote tricky stuff, e.g.,
 >>> r'''"\n'\x07'"'''
 '"\\n\'\\x07\'"'
 >>> print r'''"\n'\x07'"'''
 "\n'\x07'"
 >>> eval( r'''"\n'\x07'"''' )
 "\n'\x07'"
 >>> eval(eval( r'''"\n'\x07'"''' ))
 '\x07'
 >>> print eval(eval( r'''"\n'\x07'"''' ))

(it beeped ;-)

Alternatively, you can give simple names to the nasty stuff:

 >>> q3s="'''"
 >>> beep_rep = r'\x07'

Then use them:
 >>> print "q3s=[%(q3s)s] beep_code = %(beep_rep)s" % vars()
 q3s=['''] beep_code = \x07
 
Or you can use the pieces-of-string-in-() trick to spell it out,
with comments even:

 >>> print (
 ...     "q3s=["
 ...     "%(q3s)s"        #this will grab the q3s value
 ...     "] beep_code = " #just another piece of the string
 ...     "%(beep_rep)s"   # this interpolates the last variable
 ...     % vars()         # and this should do it after another ')'
 ... )
 q3s=['''] beep_code = \x07

You can also put your trick strings in a dictionary to use with %
instead of cluttering local namespace:

 >>> d={'q3s':"'''", 'beep_rep':r'\x07'}
 >>> print "q3s=[%(q3s)s] beep_code = %(beep_rep)s" % d
 q3s=['''] beep_code = \x07

Thought this might give you some additional ideas for coding your string stuff.

Regards,
Bengt Richter



More information about the Python-list mailing list