It means it will return None. You could remove the return and it would still return None because all functions that don't specify a return value in python will by default return None.
In this particular case it means the code will go no further if the object has the attribute 'moved_away', without the return any code below would be evaluated even if the if statement evaluated to True.
So you can think of it as being similar to a break statement in a loop when you have a condition you want to exit the loop on, without the break the code would continue to be evaluated.
if hasattr(self, 'moved_away'): # if this is True we return/end the function
return
# if previous statement was False we start executing code from here
Answer from Padraic Cunningham on Stack OverflowSeveral weeks ago a was pursuing some of the posts here on python and stumbled on an article about bad programming habits. I cant find the article again for reference but right at the top was a heady warning to avoid returning a meaningful None. AT the time I thought, 'well thats just droll and I never do that anyway', but as it turns out I do it all the time. If the function finds the correct thing then return the correct thing otherwise just end the function and python will return None for you.
So do you guys do the same thing? Whats wrong with returning None in the first place? What strategies do you use to avoid returning None?
Might not be exactly on topic but I wish more people would code their functions to NOT return None and instead return expected type.
BeautifulSoup is the biggest perpetrator of this. Whenever you parse the tree/soup you'll either get a list of results or a single result, now if no results are found instead of getting an empty list you get None returned, which in turn requires you to make checks on every single lookup which really messes up your code up and makes everything look ridiculous.
switched to lxml/xpath and never looked back.
Per PEP-20, explicit is better than implicit, so when I'm writing code where None is a valid answer, I explicitly return a None. If it's an error to get to the end, raise an error.
If it's a hack/preliminary code, I don't care. For production level code, I have one return and it's the last line of the function/method. For a short function, I don't really care, but definitely for a long function.
It means it will return None. You could remove the return and it would still return None because all functions that don't specify a return value in python will by default return None.
In this particular case it means the code will go no further if the object has the attribute 'moved_away', without the return any code below would be evaluated even if the if statement evaluated to True.
So you can think of it as being similar to a break statement in a loop when you have a condition you want to exit the loop on, without the break the code would continue to be evaluated.
if hasattr(self, 'moved_away'): # if this is True we return/end the function
return
# if previous statement was False we start executing code from here
return exits the current function.
So, here it will stop the execution & return None.
On the actual behavior, there is no difference. They all return None and that's it. However, there is a time and place for all of these.
The following instructions are basically how the different methods should be used (or at least how I was taught they should be used), but they are not absolute rules so you can mix them up if you feel necessary to.
Using return None
This tells that the function is indeed meant to return a value for later use, and in this case it returns None. This value None can then be used elsewhere. return None is never used if there are no other possible return values from the function.
In the following example, we return person's mother if the person given is a human. If it's not a human, we return None since the person doesn't have a mother (let's suppose it's not an animal or something).
def get_mother(person):
if is_human(person):
return person.mother
else:
return None
Using return
This is used for the same reason as break in loops. The return value doesn't matter and you only want to exit the whole function. It's extremely useful in some places, even though you don't need it that often.
We've got 15 prisoners and we know one of them has a knife. We loop through each prisoner one by one to check if they have a knife. If we hit the person with a knife, we can just exit the function because we know there's only one knife and no reason the check rest of the prisoners. If we don't find the prisoner with a knife, we raise an alert. This could be done in many different ways and using return is probably not even the best way, but it's just an example to show how to use return for exiting a function.
def find_prisoner_with_knife(prisoners):
for prisoner in prisoners:
if "knife" in prisoner.items:
prisoner.move_to_inquisition()
return # no need to check rest of the prisoners nor raise an alert
raise_alert()
Note: You should never do var = find_prisoner_with_knife(), since the return value is not meant to be caught.
Using no return at all
This will also return None, but that value is not meant to be used or caught. It simply means that the function ended successfully. It's basically the same as return in void functions in languages such as C++ or Java.
In the following example, we set person's mother's name and then the function exits after completing successfully.
def set_mother(person, mother):
if is_human(person):
person.mother = mother
Note: You should never do var = set_mother(my_person, my_mother), since the return value is not meant to be caught.
Yes, they are all the same.
We can review the interpreted machine code to confirm that that they're all doing the exact same thing.
import dis
def f1():
print "Hello World"
return None
def f2():
print "Hello World"
return
def f3():
print "Hello World"
dis.dis(f1)
4 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f2)
9 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
10 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f3)
14 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Python and I are NOT getting along today.
I have the script below, which takes arguments like username and fromdate and passes it into the appropriate place in the URL (the link variable). Now, if the user just inputs username and doesn't input fromdate, Python will return None instead of nothing. Why do you do this, Python!? I never asked you to!
How can I avoid this monstrosity?
Command
main.py -u jacksfilms
Script
import requests, re, argparse
parser = argparse.ArgumentParser()
parser.add_argument('-u','--username', required=False)
parser.add_argument('-from','--fromdate', required=False)
parser.add_argument('-to','--todate', required=False)
args = vars(parser.parse_args())
username = args['username']
fromdate = args['fromdate']
todate = args['todate']
link = "https://web.archive.org/cdx/search/cdx?url=twitter.com/{}/status&matchType=prefix&from={}&to={}".format(username,fromdate,todate)
data = []
c = requests.get(link).text
urls = re.findall(r'https?://[^\s<>"]+[|www\.^\s<>"]+', c)
for i, url in enumerate (urls):
data.append(f"{i}: {url}\n")
print(data)Raise an
IndexErrorif the item is not found. This is what Python'slistdoes. (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
dictjust raises aKeyErrorwhen 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
-1because that's what"".finddoes, or throwing aValueErrorbecause that's what[].indexdoes (I don't mean the first option is the best one). I would never use one-based indices, so the value0is 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
Nonespecially. 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 usingNoneor throwing an exception for this case.The meaning of an example is unclear, especially given that
Noneis a valid dictionary key. But if I had to use some special value where string is normally expected, I would prefer it to beNone(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).
There is no such thing as "returning nothing" in Python. Every function returns some value (unless it raises an exception). If no explicit return statement is used, Python treats it as returning None.
So, you need to think about what is most appropriate for your function. Either you should return None (or some other sentinel value) and add appropriate logic to your calling code to detect this, or you should raise an exception (which the calling code can catch, if it wants to).
To literally return 'nothing' use pass, which basically returns the value None if put in a function(Functions must return a value, so why not 'nothing'). You can do this explicitly and return None yourself though.
So either:
if x>1:
return(x)
else:
pass
or
if x>1:
return(x)
else:
return None
will do the trick.
I get the general idea that None is a type when there is no specific value to be return.
But I am just confused on how to explicitly have a value of "None" . I am still learning python so I want to understand in which case does a function returns the value of "None". Like, it would also be helpful is someone could share a short function that displays "None" , preferably with no "return".
I've search online and there was an example of print(print("hi")), I kind of get this, the interpreter displays the first print and the second one is "None" because there is no value.
Thanks in advance
For example, I have a function that saves data as a csv file and this function does not have a return value.
I’m unsure as to whether or not this is bad practice? I could return 0 to indicate that the data saved successfully and 1 to denote otherwise, but I’ve already got Raise Error in the save function so this feels unnecessary.
There is nothing wrong with returning None.
In most cases, you don't need to explicitly return None. Python will do it for you. This is an altered version of your foobar which behaves identically without explicitly returning None:
def foobar(arg):
if check:
return result
# If not check, then None will be returned
Still, even if Python implicitly returns None, there is a value in being explicit; Your code becomes easier to read and understand. This is a constant trade-off for which there is no general answer.
I think returning None is a "no go" from a usability standpoint rather than style. As briefly mentioned in this answer, consider raising an exception instead. For example:
def foobar(arg):
# connect to page by httplib
# check for arg in a certain pattern by lxml
if not check:
raise ValueError("arg did not match pattern in lxml")
return result
try:
result = foobar(arg)
except ValueError:
result = None
if result is not None:
# do stuff
else:
# do other stuff
The advantage of this approach is that it makes it explicit when there is not a match. Other people using your function won't need to know that None is the return value they should expect when there isn't a match and they can handle the exception as they see fit.