Question

I have a function which searches for results to a query. If there's no results what is recommended to return, False or None?

I suppose it's not that important but I'd like to follow best practice.

Was it helpful?

Solution 2

I would definitely not return False. But there are other options than just None vs. False.


A positive result would be a short string in this case.

So, a negative result can be an empty string. (Unless that's also a possible positive result, of course.)

As PEP 8 says:

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

But that's not a complete answer to your question (nor is it an iron-clad rule in the first place). You have to think through the pros and cons and decide which are most important in your actual use.


I think the biggest issue is this: If you return '', code that tries to use the result as a string will work. If you return None, that same code will raise an exception.

For example, here's a simplified version of some code I've got lying around:

result = query_function(foo, bar)
soup = bs4.BeautifulSoup(result)
for div in soup.find_all('div'):
    print(div['id'])

My query_function returns '', so the code will successfully print out no IDs. That's what I want for my script. But for a different use case, it might be better to raise an exception. In that case, I'd make query_function return None.


Or, of course, you can just make query_function itself raise an exception, as in Aya's answer.


You may want to look over the standard string methods, re methods, and other search functions in the stdlib (maybe even look at sqlite, etc.) to see what they do. (Note that in a few cases, there are matching pairs of value-returning and exception-raising functions, like str.find and str.index, so the answer might not be either one or the other, but both.)

OTHER TIPS

A positive result would be a short string in this case.

Assuming you have something like this (extremely trivial) example...

the_things = {'foo', 'bar'}

def find_the_thing(the_thing):
    if the_thing in the_things:
        return the_thing

...it will return None by default if the thing is not found, which is okay, and you can use it like this...

the_thing = find_the_thing('blah')
if the_thing is not None:
    do_something_with(the_thing)
else:
    do_something_else()

...but it's sometimes better to raise an exception like this....

the_things = {'foo', 'bar'}

def find_the_thing(the_thing):
    if the_thing in the_things:
        return the_thing
    raise KeyError(the_thing)

...which you can use like this...

try:
    do_something_with(find_the_thing('blah'))
except KeyError:
    do_something_else()

...which might be more readable.

I would return an empty list, it will save you headaches when looking at the return values of this function down the road.

If you want your program to die when you make assumptions that the list has elements however, None is a good choice.

How about not returning anything but yielding the results one by one? Generators are generally a convenient thing, as they avoid building up lists that are then used and discarded one by one anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top