Что это за "и" выражение, действительно делающее в обратном?

Я пытаюсь лучше понять следующий код python и почему автор использовал оператор "AND" в возврате.

def valid_password(self, password):
        PASS_RE = re.compile(r'^.{6,128}$')
        return password and PASS_RE.match(password)

далее вниз код...

if not self.valid_password(self.password):
    params['error_password'] = "Please enter a valid password."

Я попытался проверить результирующий объект, который передается обратно вызывающему, однако я все еще не совсем понимаю, как это работает.

Кажется, что это возвращает пароль обратно вызывающему и логическое значение того, действительно ли пароль действителен, однако я не понимаю, как вызывающая функция может проверять bool объекта? Это что-то основное в Python, которое я пропустил?

Существует другой пример аналогичного использования рядом с этим, однако он использует оператор "или", который для меня еще более запутанным:

def valid_email(self, email):
    EMAIL_RE  = re.compile(r'^[\S][email protected][\S]+\.[\S]+$')
    return not email or EMAIL_RE.match(email)

Любые советы о том, что здесь происходит, будут очень признательны. Код работает и делает то, что вы ожидаете от него, проверяет ввод на регулярное выражение и возвращает True или False, однако мне бы очень хотелось понять, что он был написан так, а не просто возвращать bool.

Ответ 1

В Python оба and и or вернут один из своих операндов. С or, Python проверяет первый операнд и, если он является "правдивым" значением (подробнее об истинности позже), он возвращает первое значение без проверки второго (это называется логической оценкой ярлыка, и это может быть важно), Если первый "falsey", то Python возвращает второй операнд, независимо от того, что он:

Python 2.7.3 (default, Jan  2 2013, 13:56:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 or 3
2
>>> 0 or 3
3

С "и" происходит то же самое: сначала проверяется первый операнд, и если он "ложный", то Python никогда не проверяет второй операнд. Если первый операнд "правдивый", то Python возвращает второй операнд, независимо от того, что он:

>>> 2 and 3
3
>>> 0 and 3
0
>>> 3 and 0
0
>>> 3 and []
[]
>>> 0 and []
0

Теперь поговорим о "правдивости" и "ложности". Python использует следующие правила для оценки вещей в булевом контексте:

  • Следующие значения: "false": False, None, 0 (ноль), [] (пустой список),() (пустой кортеж), {} (пустой dict), пустой набор, (пустая строка)
  • Все остальное "правдиво"

Итак, что-то вроде password and PASS_RE.match(password) использует оценку короткого замыкания на Python. Если password - None, то оператор and просто вернет None и никогда не будет оценивать вторую половину. Это хорошо, потому что PASS_RE.match(None) вызвало бы исключение. Смотрите это:

>>> 3 or []
3
>>> [] or 3
3
>>> 0 or []
[]
>>> [] or 0
0
>>> 0 and []
0
>>> [] and 0
[]

Посмотрите, как работает короткое замыкание? Теперь смотрите это:

>>> value = "hello"
>>> print (value.upper())
HELLO
>>> print (value and value.upper())
HELLO
>>> value = None
>>> print (value.upper())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'upper'
>>> print (value and value.upper())
None

Посмотрите, как функция короткого замыкания and помогла нам избежать трассировки? Что происходит в этой функции.

Ответ 2

Соответствующая строка проверяет, что пароль "правша" и соответствует регулярному выражению предопределенного пароля.

Вот как он ломается:

  • Функция возвращает password, если password 'falsey'.

  • Если пароль "правдивый", но пароль не соответствует регулярному выражению пароля, функция возвращает None.

  • Если есть "правдивый" пароль и он соответствует регулярному выражению, возвращается объект соответствия .

Оператор and является оператором короткого замыкания; Если первое значение является "правным", оно возвращает второе значение. В противном случае оно возвращает первое значение.

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

Ответ 3

Вам просто нужно знать, что:

Таким образом,

a = '1'
print('' and a)

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

и

a = '1'
print('' or a)

печатает '1', потому что пустая строка False, вторая часть должна быть оценена, чтобы дать результат выражения.