The best and most accurate way to think of
pass is as a way to explicitly tell the interpreter to do nothing. In the same way the following code:
means “if I call the function foo(x, y), sum the two numbers the labels x and y represent and hand back the result”,
means “If I call the function bar(), do absolutely nothing.”
The other answers are quite correct, but it’s also useful for a few things that don’t involve place-holding.
For example, in a bit of code I worked on just recently, it was necessary to divide two variables, and it was possible for the divisor to be zero.
c = a / b
will, obviously, produce a ZeroDivisionError if b is zero. In this particular situation, leaving c as zero was the desired behavior in the case that b was zero, so I used the following code:
c = a / b
Another, less standard usage is as a handy place to put a breakpoint for your debugger. For example, I wanted a bit of code to break into the debugger on the 20th iteration of a for… in statement. So:
for t in range(25):
if t == 20:
with the breakpoint on pass.