4

In response to another question of mine, someone suggested that I avoid long lines in the code and to use PEP-8 rules when writing Python code. One of the PEP-8 rules suggested avoiding lines which are longer than 80 characters. I changed a lot of my code to comply with this requirement without any problems. However, changing the following line in the manner shown below breaks the code. Any ideas why? Does it have to do with the fact that what follows return command has to be in a single line?

The line longer that 80 characters:

    def __str__(self):
    return "Car Type \n"+"mpg: %.1f \n" % self.mpg + "hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc + "unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)

The line changed by using Enter key and Spaces as necessary:

    def __str__(self):
    return "Car Type \n"+"mpg: %.1f \n" % self.mpg + 
                   "hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc +
                   "unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)
2
  • first off get rid of the string concatenation and use %s replacement that will shorten up the line considerably. Something like this. 'Car Type \nmpg: %.1f \n %d hp: %.2f \npc: %i \nunit cost: $%.2f \nprice: $%.2f' % (self.mpg, self.hp, self.pc, self.cost, self.price) you could even name the replacements to make it clearer what you are doing. Commented May 8, 2010 at 4:04
  • 1
    That PEP suggestion is very poor and out of date; squashing code to 79 columns is an excellent way to result in mangled, unreadable code, as the PEP example itself demonstrates vividly. 120 columns is far more reasonable, forcing much fewer lines to be split. 80 column screens are not a serious development environment. Commented May 8, 2010 at 16:53

4 Answers 4

13

A multiline string would be more readable:

def __str__(self):
    return '''\
Car Type
mpg: %.1f
hp: %.2f 
pc: %i 
unit cost: $%.2f
price: $%.2f'''% (self.mpg,self.hp,self.pc,self.cost,self.price)

To maintain visually meaningful indentation levels, use textwrap.dedent:

import textwrap
def __str__(self):
    return textwrap.dedent('''\
        Car Type
        mpg: %.1f
        hp: %.2f
        pc: %i
        unit cost: $%.2f
        price: $%.2f'''% (self.mpg,self.hp,self.pc,self.cost,self.price))
Sign up to request clarification or add additional context in comments.

1 Comment

The problem with this method is indentation. It's ugly to have no indentation with the long string.
6

You can solve the problem by putting the expression in parenthesis:

def __str__(self):
    return ("Car Type \n"+"mpg: %.1f \n" % self.mpg + 
            "hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc +
            "unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price))

However, I'd consider writing it more like this: (code untested)

def __str__(self):
    return """\
Car Type 
mpg: %(mpg).1f 
hp: %(hp).2f
pc: %(pc)i 
unit cost: $%(cost).2f 
price: $%(price).2f """ % self.__dict__

3 Comments

Note that there's any number of reasons for foo.bar not to be equivalent to foo.__dict__['bar'].
@Mike Emphasis on "I'd consider". If I'm writing __str__, I probably know if they're equivalent or not.
vars(self) looks cleaner than self.__dict__ (It does the same)
4

Python doesn't let you end a line inside an expression like that; the simplest workaround is to end the line with a backslash.

def __str__(self):
    return "Car Type \n"+"mpg: %.1f \n" % self.mpg + \
           "hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc + \
           "unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)

In this case, the backslash must be the last character on the line. Essentially, it means "ignore the fact that there's a newline here". Or in other words, you're escaping the newline, since it would normally be a significant break.

You can escape an otherwise significant newline at any time with a backslash. It would be silly, but you could even do

def foo():
  return \
   1

so that foo() would return 1. If you didn't have the backslash there, the 1 by itself would cause a syntax error.

1 Comment

A nicer workaround is to put parentheses around the expression.
3

It require a little extra setup, but a data-driven approach (with a good dose of vertical alignment) is easy to grok and modify as a project evolves. And it indirectly eliminates the problem of long lines of code.

def __str__(self):
    dd = (
        ("Car Type     %s",    ''),
        ("  mpg:       %.1f",  self.mpg),
        ("  hp:        %.2f",  self.hp),
        ("  pc:        %i",    self.pc),
        ("  unit cost: $%.2f", self.cost),
        ("  price:     $%.2f", self.price),
    )

    fmt = ''.join("%s\n" % t[0] for t in dd)
    return fmt % tuple(t[1] for t in dd)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.