Question

More specifically, I'm not sure what the "%" and "\" symbols coming right after each other are supposed to mean:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % \
    (self.id, a, b, c, d, e, f)

Is this return statement considered to be one line of code? Because I originally thought the "\" was there to chop up what seems to be an excessively long line into two pieces to enhance readability and to avoid wrap-around.

Also, I the tabulation here reflects what is in my code. The part that says '(self.id, a, b, c, d, e, f)' is indeed tabbed once further than the beginning of the return statement.

Basically, is the statement equivalent to:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % (self.id, a, b, c, d, e, f)

in this one there is no "\" involved....

Was it helpful?

Solution

The % symbol is known as the string formatting or string interpolation operator and is described in String Formatting Operations. Also, note that in my examples I moved the % symbol to the next line instead of leaving it on the end of the previous line. Both forms are valid, however putting it on the same line as the data used for interpolation tends to make it clearer to read and easier to maintain.

Yes, the two pieces of code are equivalent since the backslash treats two or more physical lines as a single logical line as described in the Python documentation about the \ symbol in the section about Explicit Line Joining. However I would avoid using explicit line joining and instead use this third equivalent way called Implicit Line Joining:

return ('guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }'
        % (self.id, a, b, c, d, e, f))

Because it is less prone to errors when reformatting and also allows you to use comments, such as in this reformatted example:

return ('guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' 
        % (self.id, 
           a, 
           b, 
           # c1, 
           c2, 
           d, 
           e, 
           f))

Try doing that same thing with backslashes... not only is it more arduous, but you also cannot use comments.

Note that the parentheses around the return value are not superfluous as some have suggested; they are what allows the use implicit line joining in the context of the variable interpolation (which is separate from the tuple following the % which is an additional context where implicit line joining also happens):

Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes.

In summary... please avoid explicit line joining with backslashes wherever possible! (It is almost never necessary given the alternatives).

A related subject to explicit/implicit line joining is the use of triple-quoted strings discussed in the section on String Literals. Given the C-style block syntax of your guitar example, I expect it would probably be valid to reformat your return value into multiple lines like this:

class c(object):
    def f(self):
        return """
guitar {
  id: %d, 
  relevant_properties: (%.02f, %.02f, %.02f),
  irrelevant_properties: (%.02f, %.02f, %.02f)
}
""" % (self.id, a, b, c, d, e, f)

I have put this example in the fuller context of a class method definition so it will be clearer what the formatting will look like; the multi-line string will be flush against the left side of the buffer and any spaces will appear verbatim in the output.

Be aware, however, the formatting above may introduce unwanted leading or trailing newlines, so this is one of the few cases where I occasionally recommend the use of explicit line joining. The reason here is to eliminate unwanted extra newline characters as a trade-off for the enhanced code-readability that triple-quoted strings gives us since it allows us to see the complete stanza more or less the way we would see it in the final output; comparing above you'll see just the addition of a single \ character at the end of the first occurrence of the """:

class c(object):
    def f(self):
        return """\
guitar {
  id: %d, 
  relevant_properties: (%.02f, %.02f, %.02f),
  irrelevant_properties: (%.02f, %.02f, %.02f)
}
""" % (self.id, a, b, c, d, e, f)

OTHER TIPS

Yes, the \ at the end of a line escapes the newline so those two pieces of code are equivalent.

It is described here: http://docs.python.org/reference/lexical_analysis.html#explicit-line-joining

Yes, what you have there is a simple string format broken across two lines. The backslash operator simply allows you to break python statements on to multiple lines (since Python is whitespace sensitive).

The backslash character makes python ignore the newline at the end of the first line (cf. the docs). So yes, your two pieces of code are indeed equivalent.

Because I originally thought the "\" was there to chop up what seems to be an excessively long line into two pieces to enhance readability and to avoid wrap-around.

It is. What do you find confusing?

After the line is joined up, you just get a long string followed by a % followed by a tuple. This has the usual meaning; % is used for string interpolation.

In a script, opened with IDLE, I obtained the following indentation in the following function's body:

def f(self, a, b, c, d, e, f):
    return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % \
           (self.id, a, b, c, d, e, f)

To obtain this indentation, place the cursor between (%.02f, %.02f, %.02f) }' % \ and (self.id, a, b, c, d, e, f) , then click on ENTER

If I copy, here on SO, only the two lines of the above function's body , without clicking on {} button, I obtain:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }' % \
       (self.id, a, b, c, d, e, f)

The indentation in aculich's answer is correct , and the one in your question is not really incorrect (because your code will work without giving an error) but not visually pleasant.

.

Personally, I think it's preferable to put the operating sign % on the line following \ rather than before it, like that:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }'\
       % (self.id, a, b, c, d, e, f)

.

One can improve the display so that the width is reduced, like that:

return ('guitar '
        '{ '
        'id: %d, '
        'relevant_properties: (%.02f, %.02f, %.02f), '
        'irrelevant_properties: (%.02f, %.02f, %.02f) '
        '}') \
        % (self.id, a, b, c, d, e, f)

Bouaif (that's personal french onomatopoeia trying to express doubt), that's not fantastic, because it mixes implicit and explicit line joining.

EDIT: then, taking account of aculich's explanations, the above reduced-width solution can also be written

return ('guitar '
        '{ '
        'id: %d, '
        'relevant_properties: (%.02f, %.02f, %.02f), '
        'irrelevant_properties: (%.02f, %.02f, %.02f) '
        '}'
        % (self.id, a, b, c, d, e, f) )

Well, that has got more style.

But I hesitate in knowing which one I prefer among this latter one and the following manner that came to my mind while thinking about all that:

return ('guitar '
        '{ '
        'id: %d, '
        'relevant_properties: (%.02f, %.02f, %.02f), '
        'irrelevant_properties: (%.02f, %.02f, %.02f) '
        '}'
        ) % (self.id, a, b, c, d, e, f)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top