Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "and" in return

I'm taking Web Application Engineering course on Udacity. I noticed that the instructor use and operator in return statement in his validation method. And I didn't understand how it is possible to return 2 arguments. I think, it may be something like if statement. Could anyone explain what it actually is?

Here is the validation method:

USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
def valid_username(username):
    return username and USER_RE.match(username)

Thanks in advance.

like image 859
user1272724 Avatar asked Jul 22 '12 23:07

user1272724


2 Answers

The and operator evaluates whether both of its arguments are tru-ish, but in a slightly surprising way: First it examines its left argument. If it is truish, then it returns its right argument. If the left argument is falsish, then it returns the left argument.

So the last line in your code:

return username and USER_RE.match(username)

is the same as:

if username:
    return USER_RE.match(username)
else:
    return username

Strings like username are truish if they are not empty. The regex match function returns a truish match object if the pattern matches, and returns None, a falsish value, if it doesn't match.

The net result is that valid_username will return a truish value if username is not an empty string, and the username matches the given pattern.

Note the "and" here has nothing to do with returning two values, it's computing one value.

like image 88
Ned Batchelder Avatar answered Oct 01 '22 07:10

Ned Batchelder


When you use a logical operator, it continues according to the rules, so with and, it evaluates the truthiness of the first statement and if it isn't truthy, it returns a non-truthy value (in the first case, '').

print repr("" and "THIS IS POST AND")
""

print "" or "THIS IS POST AND"
THIS IS POST AND

print None or "Something else"
Something else

Where this comes in handy is when you don't want to call a non-existent method on something like None (e.g. the length trait):

r = None

s = [1,2,3,4]

print r and len(r)
None

print s and len(s)
4

In the case you posted, the point is that you only want to check the username against the regular expression if the username is truthy.

It's important to note here that and, and or both short-circuit. So if you get something non-truthy, the function won't even evaluate the regular expression.

like image 41
Jeff Tratner Avatar answered Oct 01 '22 09:10

Jeff Tratner