"pass" same as "return None" in Python?
Question:
I have been learning python about a week now, below is the question:
Code
def Foo():
pass
def Bar():
return None
Usage
a = Foo()
print(a)
# None
b = Bar()
print(b)
# None
Question:
1. Why do we need pass when we already have return None? Is there some scenario that return None can not handle but pass can?
Answers:
Examples which should answer both questions:
Pass can be used in exception handling:
try:
something()
except:
pass # does not return
this_still_executes()
Pass can be used to declare classes without any new elements:
class CustomError(Exception):
pass
Another scenario is that pass
means something hasn’t been implemented for now, but will be implemented in the future. For example, before writing the actual logic, you define some APIs:
def get():
pass
def post():
pass
def put():
pass
...
This semantic meaning cannot be replaced by return None
. And like viraptor said, sometimes you’ll get syntax error if you use return None
rather than pass
.
pass
is an “empty” command, but return
stops the function / method.
Examples:
def func():
do_something() #executed
pass
do_something_else() #also executed
but:
def func2():
do_something() #executed
return None
do_something_else() #NOT executed
In the second case, return None
is: “stop the function and return None”.
But pass
is just like “go to the next line”
>>> import dis
>>> dis.dis(Foo)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>> dis.dis(Bar)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
As you can see these are exactly the same functions. There’s no reason to use one over another (in this concrete example) except for style and maybe for telling other coders what is the intention for the function.
Generally there is a difference though. return
statement interrupts the execution of current function while pass
does not.
In languages like Python, you have two types of ‘things’ being evaluated: expressions and statements. Expressions are, well, expressions, which evaluate to something. For instance 1
, 1+1
, or f(x)
are all expressions, evaluating to something.
By comparison, statements are not ‘returning’ anything, instead, they ‘act on the environment’. For instance, x=3
sets the variable x
to the value 3
. def f(x): return x + 1
sets the value of f
to a function. That doesn’t ‘evaluate’ to anything, that modifies the current environment where things are evaluated.
With this in mind, you sometimes need an empty statement. For syntactic reasons, there are places in Python where you need a statement, but if you don’t want anything to happen here, you might want to express that what happens is precisely ‘nothing’. One way would be to evaluate an expression and do nothing with it:
def f():
1
But a casual glance at that might suggests that this function returns 1
: instead, you can use pass
as explicitely stating: ‘do nothing’:
def f():
pass
Now, there’s another catch: I mentioned earlier that f(x)
is an expression. But in the two examples above, I’ve not put any return
, so what do these evalute to ? The answer is: a function call returns (i.e. evaluates to) None
, unless specified otherwise. So:
def f():
pass
def g(x):
if x > 2:
return x
def h():
return None
f() # None
g(3) # 3 -> we explicitely say `return x`
g(1) # None -> no return specified for that path
h() # None -> we explicitely say `return None`
Others have mentioned that pass can be used in other places (e.g. within empty classes, in exception handling…). The reason for this is that all of these require some statement, and pass
allows to specify an empty one. This, combined with the fact that a function returns None
except specified otherwise, leads to the behaviour you observe (although they are conceptually different).
All functions/methods/callables in Python return None
in the end, unless you manually return any other value, of course. You could imagine that every function has an implicit return None
statement after all of your custom code. If you exit the function earlier using your own return
statement, it simply does not get reached and has no effect. Also a bare return
with no value automatically returns None
as default.
The pass
statement (“do nothing”) is needed in this language, because we define code blocks using different indentation levels and not using brackets (e.g. { ... }
in C, Java, etc.) or keywords (e.g. if ... fi
in Bash).
So if you need an empty code block somewhere (function that doesn’t do anything yet, empty class, empty exception catcher, …), in other languages you simply put nothing between the opening and closing bracket or keyword. In Python, you need an indented piece of code, else it’s a syntax error. Therefore we have pass
– to do nothing although we have to write code in that place.
Some examples:
-
class MyPersonalException(Exception):
# simple exception without any additional information or functionality
# 'return None' would not work.
pass
-
def lazy_function():
# too lazy to do anything...
# often used if a method needs to be implemented to match an interface,
# but should not do anything.
# 'return None' would work here as well.
-
try:
# [do something here]
catch:
# we don't have to do anything if it fails, just catch and suppress the exception
pass
So pass
simply means to do nothing and just go on with processing the next line.
Summary:
return None
is (or can imagined to be) always implicitly added below the last line of every function definition. It can also only appear in functions and immediately exits them, returning a value (or None
as default).
pass
has no semantic meaning, it does not get interpreted in any way. Its only purpose is to allow the creation of empty code blocks which would not be possible otherwise in Python, as we don’t use brackets etc. to surround blocks. It can be written anywhere and always does the same: nothing.
I have been learning python about a week now, below is the question:
Code
def Foo():
pass
def Bar():
return None
Usage
a = Foo()
print(a)
# None
b = Bar()
print(b)
# None
Question:
1. Why do we need pass when we already have return None? Is there some scenario that return None can not handle but pass can?
Examples which should answer both questions:
Pass can be used in exception handling:
try:
something()
except:
pass # does not return
this_still_executes()
Pass can be used to declare classes without any new elements:
class CustomError(Exception):
pass
Another scenario is that pass
means something hasn’t been implemented for now, but will be implemented in the future. For example, before writing the actual logic, you define some APIs:
def get():
pass
def post():
pass
def put():
pass
...
This semantic meaning cannot be replaced by return None
. And like viraptor said, sometimes you’ll get syntax error if you use return None
rather than pass
.
pass
is an “empty” command, but return
stops the function / method.
Examples:
def func():
do_something() #executed
pass
do_something_else() #also executed
but:
def func2():
do_something() #executed
return None
do_something_else() #NOT executed
In the second case, return None
is: “stop the function and return None”.
But pass
is just like “go to the next line”
>>> import dis
>>> dis.dis(Foo)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>> dis.dis(Bar)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
As you can see these are exactly the same functions. There’s no reason to use one over another (in this concrete example) except for style and maybe for telling other coders what is the intention for the function.
Generally there is a difference though. return
statement interrupts the execution of current function while pass
does not.
In languages like Python, you have two types of ‘things’ being evaluated: expressions and statements. Expressions are, well, expressions, which evaluate to something. For instance 1
, 1+1
, or f(x)
are all expressions, evaluating to something.
By comparison, statements are not ‘returning’ anything, instead, they ‘act on the environment’. For instance, x=3
sets the variable x
to the value 3
. def f(x): return x + 1
sets the value of f
to a function. That doesn’t ‘evaluate’ to anything, that modifies the current environment where things are evaluated.
With this in mind, you sometimes need an empty statement. For syntactic reasons, there are places in Python where you need a statement, but if you don’t want anything to happen here, you might want to express that what happens is precisely ‘nothing’. One way would be to evaluate an expression and do nothing with it:
def f():
1
But a casual glance at that might suggests that this function returns 1
: instead, you can use pass
as explicitely stating: ‘do nothing’:
def f():
pass
Now, there’s another catch: I mentioned earlier that f(x)
is an expression. But in the two examples above, I’ve not put any return
, so what do these evalute to ? The answer is: a function call returns (i.e. evaluates to) None
, unless specified otherwise. So:
def f():
pass
def g(x):
if x > 2:
return x
def h():
return None
f() # None
g(3) # 3 -> we explicitely say `return x`
g(1) # None -> no return specified for that path
h() # None -> we explicitely say `return None`
Others have mentioned that pass can be used in other places (e.g. within empty classes, in exception handling…). The reason for this is that all of these require some statement, and pass
allows to specify an empty one. This, combined with the fact that a function returns None
except specified otherwise, leads to the behaviour you observe (although they are conceptually different).
All functions/methods/callables in Python return None
in the end, unless you manually return any other value, of course. You could imagine that every function has an implicit return None
statement after all of your custom code. If you exit the function earlier using your own return
statement, it simply does not get reached and has no effect. Also a bare return
with no value automatically returns None
as default.
The pass
statement (“do nothing”) is needed in this language, because we define code blocks using different indentation levels and not using brackets (e.g. { ... }
in C, Java, etc.) or keywords (e.g. if ... fi
in Bash).
So if you need an empty code block somewhere (function that doesn’t do anything yet, empty class, empty exception catcher, …), in other languages you simply put nothing between the opening and closing bracket or keyword. In Python, you need an indented piece of code, else it’s a syntax error. Therefore we have pass
– to do nothing although we have to write code in that place.
Some examples:
-
class MyPersonalException(Exception): # simple exception without any additional information or functionality # 'return None' would not work. pass
-
def lazy_function(): # too lazy to do anything... # often used if a method needs to be implemented to match an interface, # but should not do anything. # 'return None' would work here as well.
-
try: # [do something here] catch: # we don't have to do anything if it fails, just catch and suppress the exception pass
So pass
simply means to do nothing and just go on with processing the next line.
Summary:
return None
is (or can imagined to be) always implicitly added below the last line of every function definition. It can also only appear in functions and immediately exits them, returning a value (or None
as default).
pass
has no semantic meaning, it does not get interpreted in any way. Its only purpose is to allow the creation of empty code blocks which would not be possible otherwise in Python, as we don’t use brackets etc. to surround blocks. It can be written anywhere and always does the same: nothing.