Стилизировать многострочные условия в операторах if?

Иногда я разбиваю длинные условия в if на несколько строк. Наиболее очевидный способ сделать это:

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

Не очень привлекательно визуально, потому что действие сочетается с условиями. Тем не менее, это естественный способ, используя правильный отступ Python для 4 пробелов.

На данный момент я использую:

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

Но это не очень красиво. : -)

Можете ли вы порекомендовать альтернативный способ?

583
задан martineau 30 May 2017 в 17:35
поделиться

10 ответов

Вы не должны использовать 4 пробелов на своей второй условной строке. Возможно, используйте:

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

кроме того, не забывайте, что пробел более гибок, чем Вы могли бы думать:

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

Оба из тех довольно ужасны все же.

, Возможно, теряют скобки (, Руководство по стилю препятствует этому хотя)?

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

Это, по крайней мере, дает Вам некоторое дифференцирование.

Или даже:

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

я думаю, что предпочитаю:

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

Вот Руководство по стилю , который (с 2010) рекомендует использовать скобки.

637
ответ дан mardlin 30 May 2017 в 17:35
поделиться

Всего несколько других случайных идей для пользы полноты. Если они работают на Вас, используйте их. Иначе Вы - вероятно, более обеспеченная попытка чего-то еще.

Вы могли также сделать это со словарем:

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

Эта опция более сложна, но можно также найти его полезным:

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, если это работает на Вас, но это - другая опция рассмотреть. Вот еще один путь:

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'

последних двух, которые я не протестировал, но понятия, должно быть достаточно для получения Вас движение, если это - то, с чем Вы хотите пойти.

(И для записи, если это - просто одна вещь времени, Вы - вероятно, просто более обеспеченное использование методики, которую Вы представили сначала. При выполнении сравнения в большом количестве мест эти методы могут улучшить удобочитаемость достаточно, чтобы заставить Вас не чувствовать себя так плохо о том, что они - вид hacky.)

1
ответ дан Jason Baker 30 May 2017 в 17:35
поделиться

Что, если мы только вставляем дополнительную пустую строку между условием и телом и делаем остальных каноническим способом?

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

    do_something

p.s. Я всегда использую вкладки, не пробелы; я не могу подстроить...

2
ответ дан Federico A. Ramponi 30 May 2017 в 17:35
поделиться

Я предлагаю переместиться and ключевое слово к второй строке и расположить с отступом все строки, содержащие условия с двумя пробелами вместо четыре:

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

Это точно, как я решаю эту проблему в своем коде. При наличии ключевого слова, поскольку первое слово в строке делает условие намного более читаемым, и сокращение количества пробелов далее отличает условие от действия.

19
ответ дан DzinX 30 May 2017 в 17:35
поделиться

"все" и "любой" хороши для многих условий того же случая типа. НО они всегда оценивают все условия. Как показано в этом примере:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print
3
ответ дан Anders Waldenborg 30 May 2017 в 17:35
поделиться

Я предпочитаю этот стиль, когда у меня есть ужасно большое если-условие:

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()
21
ответ дан gitaarik 30 May 2017 в 17:35
поделиться

Это не улучшается так, но...

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

if allCondsAreOK:
   do_something
23
ответ дан Federico A. Ramponi 30 May 2017 в 17:35
поделиться

Кто-то должен защитить использование вертикального пробела здесь!:)

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

Это делает каждое условие явно видимым. Это также позволяет более чистое выражение более сложных условий:

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

Да, мы обмениваем немного вертикальной недвижимости на ясность. Определенно стоящий того IMO.

53
ответ дан Kevin Little 30 May 2017 в 17:35
поделиться

Я обратился к следующему в вырожденном случае, где это - просто AND's или OR's.

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

Это бреет несколько символов и проясняет, что нет никакой тонкости к условию.

111
ответ дан S.Lott 30 May 2017 в 17:35
поделиться

Простите мой noobness, но это происходит, что я не так хорошо осведомлен относительно #Python как ни один из Вас здесь, но это происходит, что я нашел что-то подобным при сценариях моих собственных объектов в 3D моделировании МЕТКИ НАЧАЛА ИНФОРМАЦИИ, таким образом, я адаптирую свой алгоритм к тому из Python.

проблема, которую я нахожу здесь, является двухсторонней:

  1. Значения мой казаться внешним для кого-то, кто может попытаться дешифровать сценарий.
  2. обслуживание Кода произойдет в высокую стоимость, если те значения будут изменены (самые вероятные), или если новые условия должны быть добавлены (поврежденная схема)

Делают для обхода всех этих проблем, сценарий должен пойти как это

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

Профессионалы этого метода:

  1. Сценарий читаем.

  2. Сценарий может быть легок сохраняемый.

  3. условия являются 1 операцией сравнения к сумме значений, которая представляет желаемые условия.
  4. Никакая потребность в многоуровневых условиях

Hope это помогает Вам весь

0
ответ дан 22 November 2019 в 21:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: