Shall same datatypes be used to return from functions, or assign default values ? or None ? What is a better coding practice, and why ?
eg. Some pseudo codes in python :
/1
def my_position(): # returns a positive integer if found
if(object is present):
position = get_position()
return position # eg 2,3,4,6
else:
return None # or return -1 or 0 ??
/2
def get_database_rows():
do query to whatever database
if(rows are found):
return [list of rows]
else:
return None # or return empty list [] ?
/3
the_dictionary = {'a' : 'john','b':'mike','c': 'robert' } # values are names i.e. non empty string
my_new_var = the_dictionary.get('z', None) # or the_dictionary.get('z','') ?
Raise an IndexError
if the item is not found. This is what Python's list
does. (Or maybe return the index where the item should have lived when doing a binary search or similar operation.)
Think about what your function does, logically: if it returns a list of all items in a DB that satisfy some criterion, and there are no such items, then it makes sense to return an empty list since that allows all the usual list operations (len
, in
) to function without the need for an explicit check.
However, if the absence of the required items indicates inconsistency, then raise an exception.
My previous remark applies especially to this case: it depends on what you're going to do with the value you get. An ordinary dict
just raises a KeyError
when a key is not found. You're replacing that exception with a value, so you should know which value makes sense in the context of your program. If no value does, then just let the exception fly.
That said, returning None
is often a bad idea because it may obscure bugs. None
is the default return value in Python, so a function returning it may indicate nothing more than its author's forgetting a return
statement:
def food(what):
if what == HAM:
return "HAM!"
if what == SPAM:
return " ".join(["SPAM" for i in range(10)])
# should raise an exception here
lunch = food(EGGS) # now lunch is None, but what does that mean?
There is also another option not listed in the question: throwing an exception. It seems to be popular enough in python, and it's sometimes better to follow a common practice for your language than to look for an abstractly best solution.
As of your examples:
I would consider -1
because that's what "".find
does, or throwing a ValueError
because that's what [].index
does (I don't mean the first option is the best one). I would never use one-based indices, so the value 0
is a valid result and can't be used to represent emptyness.
I would prefer an empty list because the caller is not guaranteed to be interested in emptyness as a special case. If I want to count all rows for several queries, I'd hate to handle None
specially. If there is a logically distinct situation where the list of rows cannot be produced (as opposed to there are no matching rows), I would consider using None
or throwing an exception for this case.
The meaning of an example is unclear, especially given that None
is a valid dictionary key. But if I had to use some special value where string is normally expected, I would prefer it to be None
(and if you prefer an empty string, it's important to know for sure that you never need a valid empty string, representing nothing special but itself).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With