Подтвердить что ты не робот

Почему неявно проверять пустоту в Python?

Дзен Python говорит, что явный лучше, чем неявный.

Тем не менее, Pythonic способ проверки коллекции c для пустоты:

if not c:
    # ...

и проверка того, что коллекция не пустая, выполняется следующим образом:

if c:
    # ...

ditto для всего, что может иметь "нулевую" или "пустоту" (кортежи, целые числа, строки, ни один и т.д.)

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

4b9b3361

Ответ 1

Эта лучшая практика не без оснований.

При тестировании if object: вы в основном вызываете метод __nonzero__ объектов, который может быть переопределен и реализован в соответствии с поведением объекта.

Например, метод __nonzero__ в коллекциях возвращает логическое значение, основанное на том, что коллекция пуста или нет.

(Ссылка: http://docs.python.org/reference/datamodel.html)

Ответ 2

"Простой лучше, чем сложный".

"Чтение рассчитывается".

Возьмем, например, if users - более читаемо, что if len(users) == 0

Ответ 3

Возможно, сбрасывается первым и третьим элементом:

  • Красивая лучше, чем уродливая.
  • Простой лучше, чем сложный.

Ответ 4

if c:
    # ...

является явным. "If" явно указывает, что следующее выражение будет оцениваться в булевом контексте.

Справедливо утверждать, что

if c == 0:
    # ...

понятен, и начинающий программист может согласиться.

Но для опытного программиста (по крайней мере, этого) последнее неяснее, оно избыточно. Я уже знаю, что c будет сравниваться с 0 из-за "if"; Мне не нужно рассказывать дважды.

Ответ 5

Если вы предпочитаете, вы можете ввести if len(lst) > 0, но какой смысл? Python действительно использует некоторые соглашения, один из них состоит в том, что пустые контейнеры считаются ложными.

Вы можете настроить это с помощью object.__nonzero__(self):

Вызывается для реализации значения истины тестирование и встроенная работа BOOL(); должен возвращать False или True, или их целых эквивалентов 0 или 1. Когда этот метод не определен, __len__() вызывается, если оно определяется, и объект считается true, если его результат отличен от нуля. Если class не определяет ни __len__(), ни __nonzero__(), все его экземпляры считается истинным.

Ответ 6

Неявный логический полиморфизм является частью многих языков. Фактически, идиома

if msg:
    print str(len(msg)) + ' char message: ' + msg

возможно, происходит из c!

void print_msg(char * msg) {
    if (msg) {
        printf("%d char message: %s", (int) strlen(msg), msg);
    }
}

Нераспределенный указатель должен содержать NULL, который удобно вычисляет значение false, позволяя избежать ошибки сегментации.

Это такое фундаментальное понятие, что это мешает python отвергнуть его. На самом деле, учитывая довольно неуклюжую версию логического полиморфизма, доступную в c, сразу же (по крайней мере, мне) ясно, что python сделал это поведение более явным, разрешив любому типу иметь настраиваемое, четко определенное логическое преобразование через __nonzero__.

Ответ 7

Другие уже отметили, что это логическое продолжение традиции (по крайней мере, раньше, C, возможно, раньше), что ноль является ложным в булевом контексте, а ненулевое значение истинно. Другие также уже отметили, что в Python вы можете добиться особых эффектов с помощью специальных магических методов и т.д. (И это прямо ответит на ваш вопрос: "позволяет ли это использовать больше случаев использования?" ) Другие уже отметили, что опытные программисты на Python узнают это соглашение и будут использоваться в соглашении, поэтому он совершенно ясен и ясен для них.

Но, честно говоря, если вам не нравится это соглашение, и вы просто программируете для своего собственного удовольствия и пользы, просто не следуйте ему. Гораздо лучше быть явным, ясным и избыточным, чем быть запутанным, и почти всегда лучше ошибаться на стороне избыточности, чем обфускация.

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

Ответ 8

Пустые списки, оценивающие False и непустые списки, оценивающие True, являются таким центральным соглашением на Python, что оно достаточно явное. Если контекст if-оператора даже сообщает тот факт, что c является списком, len(c) == 0 не будет более явным.

Я думаю, что len(c) == 0 более явственно, если вы действительно хотите проверить длину, а не магическую нулевую или пустоту, потому что их оценка может отличаться от проверки длины.