Я создал небольшой скрипт на Python для переключения между двумя файлами, которые я использую для тестирования.
Мой вопрос: какой стиль формата Python подходит для следующего кода:
import filecmp
import shutil
local = "local.txt"
remote = "remote.txt"
config_file = "C:\some\path\file.txt"
shutil.copyfile( remote if ( filecmp.cmp(local, config_file ) ) else local, config_file )
Или же
shutil.copyfile( remote
if ( filecmp.cmp(local, config_file ) )
else local,
config_file )
Или же
tocopy = remote if ( filecmp.cmp( local, config_file ) ) else local
shutil.copyfile( tocopy, config_file )
Или что?
Кроме того, предпочтительный способ называть var в Python для многословных имен - это «to_copy», «tocopy», «toCopy», «ToCopy».
На самом деле вопрос был в том, чтобы убрать if: else: "ternary" для python, но однажды здесь, почему бы не повторно запросить имена переменных. Спасибо за ссылку, хотя
Для меня «y, если x else z» для меня слишком ужасно. Разделите его на if / else, как показал Грег.
Будьте осторожны с обратными косыми чертами - помните, что они рассматриваются как escape-последовательности, поэтому, если ваш путь был "C: \ some \ path \ test.txt", вы будете чесать голову, пока не поймете, что он пытается открыть "path [TAB] est. текст". Лучше использовать косую черту или, если это не удается, экранировать, используя \\ или необработанные строки.
@ Брайан: Правда? Я думал, что это преимущество перед другими языками. Вы хоть представляете, почему это сработало? (не так ли?: - /)
Здесь это сработало, потому что ни одна из строк «\ s», «\ p» или «\ f» не является допустимой escape-последовательностью. Если бы у вас был первый символ после \ be "n" ("\ n" = новая строка) или "t" ("\ t" = tab), это было бы ошибкой. (Что может быть очень загадочным, если простое изменение имени файла каким-то образом нарушает ваш код)
: o Верно !! .. У меня есть путь C: \ в опубликованном коде, но на моей машине путь не содержал ни одной из упомянутых букв. Хороший звонок! Дополнительный вопрос, могу ли я использовать "/" как в Java? например, это объявление работает на Java: новый файл ("C: /some/path/file.txt");
Наиболее распространенное именование, которое я видел, - это слова, разделенные нижним кодом, to_copy.
Что касается стиля формата, такого согласия я не видел. я нахожу
source = remote if filecmp.cmp(local, config_file) else local
shutil.copyfile(source, config_file)
чтобы быть самым ясным среди ваших вариантов.
И видя, что все предпочитают разделить, если бы я, по крайней мере, инкапсулировал вызов copyfile на случай, если вы когда-нибудь захотите его изменить:
def copy_to(source, destination):
shutil.copyfile(source,destination)
if filecmp.cmp(local, config_file):
copy_to(remote, config_file)
else:
copy_to(local, config_file)
В чем причина отрицательного голосования? Я имею в виду, что не так в этом стиле?
Вы спрашиваете о стиле Python, и это не соответствует Руководству по стилю Python - в Python удобочитаемость имеет тенденцию заменять лаконичность.
Людям это не нравится, вероятно, потому, что тернарный язык совсем новый, и старым питонистам от него больно глаза. Я нахожу это достаточно ясным, чтобы вместо этого не повторять копию файла.
Нет смысла переносить shutil.copyfile в отдельную функцию. Он добавляет одну строку кода и ничего не делает для облегчения понимания. Если позже вы захотите изменить способ копирования файла, то это не похоже на то, чтобы последние 4 строки в вашем коде были доступны только для чтения.
Вздох. Идея не в том, чтобы помочь пониманию. Это для облегчения ремонтопригодности. Конечно, нетрудно изменить две строки вместо одной, но, безусловно, легче изменить только одну, особенно если вы замените ее на две, три или пять ...
(представьте, что теперь мы скопируем файл в удаленное место по SSH). Я не могу поверить, что люди этого не понимают. Кроме того, вы предполагаете, что это происходит только в одном месте кода, и такой гарантии нет.
Я действительно не понимаю, почему это было отклонено. +1 для присвоения троичного результата именованной переменной. Если бы я мог, я бы добавил +1 за использование именованной функции, чтобы четко обозначить намерение. Я обычно делаю то же самое, но с лямбдами.
Для условного оператора я бы, вероятно, выбрал:
if filecmp.cmp(local, config_file):
shutil.copyfile(remote, config_file)
else:
shutil.copyfile(local, config_file)
В этом случае нет необходимости использовать встроенный y if x else z
, поскольку окружающий код достаточно прост.
Так вы говорите, что y if x else z должен использоваться, когда код сложный?
Я бы подумал наоборот. Когда код сложен, я бы предпочел видеть каждую вещь отдельно if: else: branch. :) ну ммххх по крайней мере для java, наверное, стиль python в этом случае другой :)
@Vinko Vrsalovic: Я согласен с комментарием о том, что строковое «if» затрудняет чтение заявления. Я думаю, что «тривиальный» - плохой выбор слов. Но строковое «если» в исходном сообщении трудно прочитать.
Я имел в виду, что окружающий код достаточно прост, чтобы не беспокоиться о его повторении (принцип DRY). Если бы это было более сложное выражение, я бы побеспокоился о дублировании слишком большого количества кода и, вероятно, вместо этого использовал бы временные переменные (как ваше третье предложение).
Я предпочитаю быть сухим, либо оплачивая стоимость троичного, либо инкапсулируя файл shutil.copy
@ Винко Врсалович: Хотя DRY очень желателен, я не думаю, что это добавляет здесь ценности. Повторение вашего интерфейса в XML - это безумие, которое предотвращает DRY. Повторение имени функции несколькими строчками кода позже - это не безумие. Локальная переменная предпочтительнее встроенной переменной if.
Это не безумие, но и в этом нет необходимости. Я защищаю локальную переменную или инкапсуляцию, см. Мой нежелательный ответ ниже.
С.Лотт, я не согласен. Я считаю, что встроенный if
более понятен, чем запись во временную переменную и последующее чтение из нее.
«запись в переменную» - фраза, которая мало что значит в объектно-ориентированном контексте. Объект будет создан как отдельный оператор или выражение. Присвоение имени этому объекту, кажется, проясняет, а не скрывает.
Из Руководство по стилю Python:
Что касается перечисления составного выражения:
Составные утверждения (несколько утверждений в одной строке) обычно не приветствуются.
Да:
if foo == 'blah':
do_blah_thing()
do_one()
do_two()
do_three()
Или для кода, который вы предоставили, пример Грега является хорошим:
if filecmp.cmp(local, config_file):
shutil.copyfile(remote, config_file)
else:
shutil.copyfile(local, config_file)
А не:
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()
Имена методов и переменные экземпляра
Используйте правила именования функций: строчные буквы со словами, разделенными подчеркиванием, по мере необходимости для улучшения читаемости.
Обновлять: По запросу Оскара также перечислено, как его код будет выглядеть таким образом.
Третий вариант кажется мне наиболее естественным, хотя использование вами пробелов в боковых скобках и лишних скобок противоречит Руководство по стилю Python.
Это руководство также отвечает на вопрос to_copy, но я бы, вероятно, вообще использовал более четкие имена.
Я бы написал это так:
import filecmp
import shutil
local = "local.txt"
remote = "remote.txt"
destination = r"C:\some\path\file.txt"
source = remote if filecmp.cmp(local, destination) else local
shutil.copyfile(source, destination)
Если вам интересно, то ведущее r в строке назначения указывает, что это «необработанная строка». Так что да, это было специально. Так что ... не удаляйте это;)
РЖУ НЕ МОГУ! Он предлагает то же решение, что и я, но вместо этого получает 3 голоса за. Удивительный :-)
Я хочу добавить, что, хотя необработанная строка была преднамеренной, я действительно не думаю, что это правильное решение. Посмотрите ответ Грега Хьюджилла, чтобы узнать немного более правильный.
Что о:
import filecmp
import shutil
local = "local.txt"
remote = "remote.txt"
config_file = "C:\some\path\file.txt"
if filecmp.cmp( local, config_file):
to_copy = remote
else:
to_copy = local
shutil.copyfile( to_copy, config_file )
yikes, это экранное имя открытого идентификатора выглядит ужасно.
Да, не надо было отказываться от имени / прозвища. :)
Есть ряд вопросов по смежным темам. См., Например, stackoverflow.com/questions/159720/….