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

Строки и операторы: лучшая практика, различия с +

Для одного из моих сайтов мне нужно проверить, определены ли несколько атрибутов класса, а не пустые. До сих пор я с радостью использовал if self.attr:, который, на мой взгляд, является сокращением для if self.attr is not None and self.attr is not '': или любым другим значением undefined атрибута.

Это прекрасно работает, но при проверке нескольких атрибутов строк уступает удивительному поведению. '' and '' не False (как я и ожидал), но ''.

Возникает вопрос: существуют ли другие типы, для которых оператор and не приводит к приведению типа к bool? Я не могу придумать пример, где это различие в поведении приведет к фактическому разному результату для if -clause (в конце концов, '' по-прежнему оценивается до False), но я оставил ощущение, что есть крайние случаи, которые могут быть ловушкой.

Наконец, я хотел бы узнать, знает ли кто, почему это было реализовано именно так? Я думал, что Zen of Python поощряет только один путь и только один путь, а оператор + уже кажется интуитивным способом конкатенации строк.

4b9b3361

Ответ 1

and никогда не прибегает к bool. Скорее, if вызывает bool() результат выражения.

Выражение с использованием andor, если на то пошло), коротких замыканий, когда оно может определить, что выражение не будет оцениваться как True или False на основе первого операнда и возвращает последнее оцениваемое значение:

>>> 0 and 'string'
0
>>> 1 and 'string'
'string'
>>> 'string' or 10
'string'
>>> '' or 10
10

Этот "побочный эффект" часто используется в коде python. Обратите внимание, что not возвращает логическое значение. Подробнее см. документацию python для логических операторов.

В документации также объясняется, что представляет собой эквивалент True или False для разных типов, например None, 0, '' и пустые контейнеры составляют False, тогда как большинство остальных эквивалентно True.

Для пользовательских классов вам необходимо определить метод .__nonzero__() (возвращает True или False) или .__len__() method (возвращает int, где 0 - False, а все остальное - True), чтобы влиять на их булевский эквивалент, в противном случае они всегда будут по умолчанию True.