Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is this "and" statement actually doing in the return?

I am trying to get a better understanding of the following python code and why the author has used the "AND" statement in the return.

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

further down the code...

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

I've tried inspecting the resulting object that gets handed back to the caller, however I still don't entirely understand how it works.

It seems like this returns the password back to the caller and a boolean of whether or not the password is valid, however I don't understand how the calling function can check the bool of an object? Is this something basic about Python that I've missed?

There is another example of a similar usage next to this one however it uses the "or" statement which to me is even more confusing:

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

Any advice on exactly what is going on here would be greatly appreciated. The code works and does what you would expect it to do, validates the input against a regular expression and returns True or False, however I would really like to understand what it was written like this and not simply returning the bool.

like image 217
Mike Fitzbaxter Avatar asked Jun 25 '13 02:06

Mike Fitzbaxter


People also ask

What does a return statement do?

A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function.

What is return statement example?

The following function searches through an array of integers to determine if a match exists for the variable number . If a match exists, the function match returns the value of i . If a match does not exist, the function match returns the value -1 (negative one).

What is the purpose of the return statement in Python?

The Python return statement is a key component of functions and methods. You can use the return statement to make your functions send Python objects back to the caller code. These objects are known as the function's return value. You can use them to perform further computation in your programs.

What is the use of a return statement in a function Mcq?

4. What is the purpose of a return statement in a function? Explanation: The return stops the execution of the function when it is encountered within the function. It returns the value to the statement where the function is called.


1 Answers

In Python, both and and or will return one of their operands. With or, Python checks the first operand and, if it is a "truthy" value (more on truthiness later), it returns the first value without checking the second (this is called Boolean shortcut evaluation, and it can be important). If the first is "falsey", then Python returns the second operand, no matter what it is:

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

With "and", much the same thing happens: the first operand is checked first, and if it is "falsey", then Python never checks the second operand. If the first operand is "truthy", then Python returns the second operand, no matter what it is:

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

Now let's talk about "truthiness" and "falsiness". Python uses the following rules for evaluating things in a Boolean context:

  • The following values are "falsey": False, None, 0 (zero), [] (the empty list), () (the empty tuple), {} (the empty dict), an empty set, "" (the empty string)
  • Everything else is "truthy"

So something like password and PASS_RE.match(password) is taking advantage of Python's short-circuit evaluation. If password is None, then the and operator will just return None and never evaluate the second half. Which is good, because PASS_RE.match(None) would have thrown an exception. Watch this:

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

See how the short-circuiting is working? Now watch this:

>>> 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

See how the short-circuiting feature of and helped us avoid a traceback? That's what's going on in this function.

like image 168
rmunn Avatar answered Nov 15 '22 21:11

rmunn