В чем смысл этого утверждения Python? - PullRequest
1 голос
/ 25 декабря 2011

Более конкретно, я не уверен, что символы «%» и «\», идущие сразу после друг друга, должны означать:

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

Считается ли это выражение возврата одна строка кода?Поскольку я изначально думал, что "\" был там, чтобы разделить то, что кажется чрезмерно длинной строкой, на две части, чтобы улучшить читаемость и избежать повторения.

Кроме того, в приведенной здесь таблице отраженомой кодЧасть, которая говорит '(self.id, a, b, c, d, e, f)', действительно вкладывается однажды дальше, чем начало оператора return.

По сути, это утверждение эквивалентно:

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

, в этом не участвует "\" ....

Ответы [ 6 ]

6 голосов
/ 25 декабря 2011

Символ % известен как оператор форматирования строки *1003* или * , и описан в Операции форматирования строки . Также обратите внимание, что в моих примерах я переместил символ % на следующую строку вместо того, чтобы оставить его в конце предыдущей строки. Обе формы действительны, однако если поместить их в одну строку с данными, используемыми для интерполяции, это делает их более понятными для чтения и более легкими в обслуживании.

Да, два фрагмента кода эквивалентны, поскольку обратный слеш обрабатывает две или более физических строки как одну логическую строку, как описано в документации Python о символе \ в разделе о явном объединении строк . Однако я бы не использовал явное объединение строк и вместо этого использовал бы этот третий эквивалентный способ, называемый Неявное объединение строк :

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

Поскольку он менее подвержен ошибкам при переформатировании, а также позволяет использовать комментарии, например, в этом переформатированном примере:

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

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

Обратите внимание, что круглые скобки вокруг возвращаемого значения не лишние , как предлагали некоторые; именно они позволяют использовать неявное соединение строк в контексте интерполяции переменных (которая отделена от кортежа после %, который является дополнительным контекстом, где также происходит неявное соединение строк):

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

В итоге ... пожалуйста, избегайте явного соединения строк с обратными слешами везде, где это возможно! (Это почти никогда необходимо, учитывая альтернативы).

Связанным предметом явного / неявного объединения строк является использование строк с тройными кавычками , описанных в разделе Строковые литералы . Учитывая синтаксис блока в стиле C вашего примера с гитарой, я думаю, что было бы правильным переформатировать возвращаемое значение в несколько строк, например:

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)

Я поместил этот пример в более полный контекст определения метода класса, чтобы было понятнее, как будет выглядеть форматирование; многострочная строка будет вровень с левой стороной буфера, и любые пробелы будут отображаться дословно в выводе.

Имейте в виду, однако, что приведенное выше форматирование может привести к нежелательным начальным или конечным переводам строки, так что это один из немногих случаев, когда я иногда рекомендую использовать явное соединение строк. Причина здесь заключается в том, чтобы исключить ненужные дополнительные символы новой строки в качестве компромисса для улучшенной читабельности кода, которую дают нам строки в тройных кавычках, поскольку это позволяет нам видеть весь раздел более или менее так, как мы его видим в конечном выводе. ; сравнивая выше, вы увидите только добавление одного \ символа в конце первого вхождения """:

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)
3 голосов
/ 25 декабря 2011

Да, \ в конце строки экранирует символ новой строки, поэтому эти два фрагмента кода эквивалентны.

Это описано здесь: http://docs.python.org/reference/lexical_analysis.html#explicit-line-joining

1 голос
/ 26 декабря 2011

В скрипте, открытом с помощью IDLE, я получил следующий отступ в теле следующей функции:

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)

Чтобы получить этот отступ, поместите курсор между (%.02f, %.02f, %.02f) }' % \ и (self.id, a, b, c, d, e, f), затем нажмитена ENTER

Если я скопирую здесь, на SO, только две строки тела вышеупомянутой функции, без нажатия кнопки {} , я получу:

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

Отступ в ответе aculich является правильным, а вопрос в вашем вопросе не совсем корректен (потому что ваш код будет работать без ошибок), но визуально не приятен.

.

Лично,Я думаю, что лучше поставить рабочий знак % на строке, следующей за \, а не перед ней, вот так:

return 'guitar { id: %d, relevant_properties: (%.02f, %.02f, %.02f), irrelevant_properties: (%.02f, %.02f, %.02f) }'\
       % (self.id, 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)

Bouaif (это личная французская звукоподражание, пытающееся выразить сомнение), это не фантастика, потому что он смешивает неявное и явное соединение линий.

РЕДАКТИРОВАТЬ: тогда, принимая во внимание объяснения aculich, вышеупомянутое решение уменьшенной ширины также может быть написано

return ('guitar '
        '{ '
        'id: %d, '
        'relevant_properties: (%.02f, %.02f, %.02f), '
        'irrelevant_properties: (%.02f, %.02f, %.02f) '
        '}'
        % (self.id, 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)
1 голос
/ 25 декабря 2011

Поскольку я изначально думал, что "\" существует для того, чтобы разделить то, что кажется чрезмерно длинной строкой, на две части, чтобы улучшить читаемость и избежать повторения.

Это так. Что вас смущает?

После объединения строки вы получите длинную строку, за которой следует %, за которым следует кортеж. Это имеет обычное значение; % используется для интерполяции строк.

1 голос
/ 25 декабря 2011

Символ обратной косой черты заставляет python игнорировать перевод строки в конце первой строки (ср. документы )Так что да, ваши две части кода действительно эквивалентны.

1 голос
/ 25 декабря 2011

Да, у вас есть простой формат строки, разбитый на две строки.Оператор обратной косой черты просто позволяет разбивать операторы Python на несколько строк (поскольку Python чувствителен к пробелам).

...