Styling multi-line conditions in 'if' stat

2019-01-03 11:20发布

Sometimes I break long conditions in ifs onto several lines. The most obvious way to do this is:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

Isn't very very appealing visually, because the action blends with the conditions. However, it is the natural way using correct Python indentation of 4 spaces.

For the moment I'm using:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

But this isn't very pretty. :-)

Can you recommend an alternative way?

30条回答
闹够了就滚
2楼-- · 2019-01-03 11:47

I'm surprised not to see my preferred solution,

if (cond1 == 'val1' and cond2 == 'val2'
    and cond3 == 'val3' and cond4 == 'val4'):
    do_something

Since and is a keyword, it gets highlighted by my editor, and looks sufficiently different from the do_something below it.

查看更多
混吃等死
3楼-- · 2019-01-03 11:49

Someone has to champion use of vertical whitespace here! :)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

This makes each condition clearly visible. It also allows cleaner expression of more complex conditions:

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

Yes, we're trading off a bit of vertical real estate for clarity. Well worth it IMO.

查看更多
劳资没心,怎么记你
4楼-- · 2019-01-03 11:49

You could split it into two lines

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

Or even add on one condition at a time. That way, at least it separates the clutter from the if.

查看更多
闹够了就滚
5楼-- · 2019-01-03 11:52

This doesn't improve so much but...

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something
查看更多
做个烂人
6楼-- · 2019-01-03 11:52

What if we only insert an additional blank line between the condition and the body and do the rest in the canonical way?

if (cond1 == 'val1' and cond2 == 'val2' and
    cond3 == 'val3' and cond4 == 'val4'):

    do_something

p.s. I always use tabs, not spaces; I cannot fine-tune...

查看更多
We Are One
7楼-- · 2019-01-03 11:52

Just a few other random ideas for completeness's sake. If they work for you, use them. Otherwise, you're probably better off trying something else.

You could also do this with a dictionary:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

This option is more complicated, but you may also find it useful:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

Dunno if that works for you, but it's another option to consider. Here's one more way:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

The last two I haven't tested, but the concepts should be enough to get you going if that's what you want to go with.

(And for the record, if this is just a one time thing, you're probably just better off using the method you presented at first. If you're doing the comparison in lots of places, these methods may enhance readability enough to make you not feel so bad about the fact that they are kind of hacky.)

查看更多
登录 后发表回答