Что это за "и" выражение, действительно делающее в обратном?
Я пытаюсь лучше понять следующий код 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, вторая часть должна быть оценена, чтобы дать результат выражения.