1

I have not seen the keyword pass used much in Python, except for the occasional exception, such as in here: Why is "except: pass" a bad programming practice? Are there any other example use-cases of pass which are acceptable/okay programming practice?

Community
  • 1
  • 1
Hari Ganesan
  • 532
  • 4
  • 18

5 Answers5

2

One use is to define a "stub" class or method that has a name but doesn't do anything. Maybe the most common case of this is to define a custom Exception class:

class MyCustomException(Exception):
    pass

Now you can raise and catch exceptions of this type. The class exists only to be raised and caught, and doesn't need any behavior associated with it.

In similar fashion, APIs may include "do-nothing" functions that are meant to be overridden in subclasses:

class SomeComplexAPI(object):
    # This method may be overridden in subclasses, but the base-class implementation is a no-op
    def someAPIHook(self):
        pass

If you didn't define the method at all, SomeComplexAPI().someAPIHook() would raise an exception because the method doesn't exist. Defining it with pass makes sure you can safely call it even if it doesn't do anything.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 1
    Arguably, the second case (the "do-nothing function" that is meant to be subclassed) should have a _docstring_ instead. That way, you can document what that function *should* do after it's overridden. – mgilson Mar 14 '14 at 19:32
  • 2
    That's true, but even when it has a docstring, I've seen people write `pass` below it anyway, just to make it clear that it's stubbed out. – BrenBarn Mar 14 '14 at 19:36
  • I use it a lot in instances like this, EG, where I'm writing something new and I know I need to have function(), but I dont know all the things I need in that function yet. Just throw a pass in there and it gives pseudo functionality that you can go back and work on later. – Josh Brown Mar 14 '14 at 19:36
  • @BrenBarn -- Yeah. I like to add the (unnecessary) `pass` there as well, but where I work they push back against it since it is "unncessary". If a pass statement actually is necessary, I'd generally say that it should be coupled with a "#TODO" type of comment. – mgilson Mar 14 '14 at 20:04
  • A more helpful alternative IMO would be to raise some sort of specific [exception](http://stackoverflow.com/questions/372042/difference-between-abstract-class-and-interface-in-python). – Hari Ganesan Mar 17 '14 at 14:47
  • @indienchild: That depends on the API. You don't want to raise an exception if it's an "optional" method and it's perfectly allowable for subclasses to not override it and just have it do nothing. – BrenBarn Mar 17 '14 at 17:57
  • @BrenBarn Very true! I was only thinking about abstract classes which require overrides – Hari Ganesan Mar 17 '14 at 20:05
2

Here are a few instances where I find myself using pass:

Renaming a class

This is a really common use. 99% of the time it's the Exception class, because it's the easiest way to avoid the bad practice of raising/excepting general exceptions. Example:

class MyModuleException(Exception):
    pass

Declaring a method on a parent class

If subclasses will all be expected to provide a certain method (and that method doesn't have default behavior) I will often define it on the parent class just for documentation purposes. Example:

class Lifeform(object):
    def acquire_energy(source, amount):
        """
        All Lifeforms must acquire energy from a source to survive, but they
        all do it differently.
        """
        pass

Preventing default behavior of inherited methods:

I use this sparingly because generally if you don't want a parent class's method it's a sign that you should either refactor the class hierarchy or that you should have a mix-in class that provides that method. Example:

class Pig(Animal):
    def fly(destination):
        """Pigs can't fly!"""
        pass

Notice here that a better solution would be to add a CapableOfFlight mix-in and remove the Animal.fly() method.

Ian Burnette
  • 1,020
  • 10
  • 16
1

To complement the other good answers, one more case where I find myself using pass is in functions with complex flow, where I want to add comments clarifying the flow. E.g.:

if A:
  if B:
    ...
  else:  # (added only to make the comment below more readable)
    # A and not B: nothing to do because ...
    pass

The else block in this example is obviously not necessary, but I sometimes add it just for making my commentary more readable.

shx2
  • 61,779
  • 13
  • 130
  • 153
  • 1
    Fun fact: in Python 3 the statement `...` is valid and will produce the same bytecode as `pass`! – Veedrac Jun 09 '14 at 13:38
0

pass is useful if you want to make a custom exception:

>>> class MyException(Exception):
...     pass
...
>>> raise MyException("error!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.MyException: error!
>>>
>>>
>>> try:
...     raise MyException
... except MyException:
...     print("error!")
...
error!
>>>

In the above example, nothing needs to go inside the class MyException because all I want is a custom exception by that name. So, I use pass as a placeholder to prevent the IndentationError that is raised by not placing anything under the class MyException(Exception) line:

>>> class MyExcpetion(Exception):
...
  File "<stdin>", line 2

    ^
IndentationError: expected an indented block
>>>
>>> class MyExcpetion(Exception):
...     pass
...
>>>
0

As a way to prevent default behavior (for one example)?

class myClass(MySuper):
  def overriddenmethod(self):
    pass  # Calls to instances of this class will do nothing when this method is called.
g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
  • I'd prefer a docstring here explicitly stating *why* this class should prevent `MySuper`'s method from being called. – mgilson Mar 14 '14 at 19:34
  • I'd prefer refactoring `MySuper` so that it doesn't have methods that it's children have to block. If that's impossible for historical reasons then I would also want a docstring here explaining the situation. – Ian Burnette Mar 26 '14 at 18:00