8

I have a piece of code that defines a function that takes a function as an argument, like so:

def stuff(n, f):
  f(n)

Now, I want to provide some default value of f that does nothing. So I figured I'd use pass, like so:

def stuff(n, f = None):
  if(f is None):
    f = pass
  f(n)

But this does not compile. How should I be doing this?

LinuxMercedes
  • 251
  • 5
  • 10

6 Answers6

19

The pass is a keyword for the interpreter, a place holder for otherwise nothing. It's not an object that you can assign. You can use a no-op lambda.

f = lambda x: None
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
Keith
  • 42,110
  • 11
  • 57
  • 76
  • OT, but why would the designers need to create a new keyword just for a noop? bizarre – jberryman Jan 01 '13 at 22:15
  • 1
    @jberryman because Python doesn't have block delimiters. In languages that do you would typically write `{}`. But in Python it would be... nothing. So `pass` is there to make it syntactically complete. – Keith Jan 01 '13 at 22:26
  • @jberryman Where? `pass` is just a keyword to act as a placeholder for otherwise empty block. It probably makes parsing easier. It's not an object. None is an object that means no other value. They have different semantics. – Keith Jan 02 '13 at 02:02
9

Why not simply this ?

def stuff(n, f=None):
    if f is None:
        return
    return f(n)
Nicolas Lefebvre
  • 4,247
  • 1
  • 25
  • 29
  • 2
    Minor improvement: [PEP8](http://www.python.org/dev/peps/pep-0008/) advises to use `is None` instead of `== None` ([rationale](http://jaredgrubb.blogspot.com/2009/04/python-is-none-vs-none.html)). – Oben Sonne Feb 28 '11 at 10:34
  • Thanks, I'd wondered which was best but never thought to check ! Answer fixed accordingly. – Nicolas Lefebvre Feb 28 '11 at 10:48
  • +1 Much better than the other solutions since it clearly states the intent. – Aaron Digulla Feb 28 '11 at 11:13
  • As far as this question has a "correct" answer, this is it. The other answers all needlessly obfuscate such a trivial function. – Glenn Maynard Feb 28 '11 at 11:39
  • If the OP wants to pass the function object on to another function, this approach does not work. – Björn Pollex Feb 28 '11 at 12:32
  • Man, I'd love to give you the answer...while this does answer exactly how I described the issue, my description was oversimplified...in my program, stuff does more than call f(n) and f(n) is called multiple times. If I could pick two answers, though,I'd pick this. – LinuxMercedes Mar 01 '11 at 09:14
  • No problem ! I as Space_C0wb0y pointed out, the correct answer depended on your exact scenario so I figured you'd pick whichever suited best :) – Nicolas Lefebvre Mar 01 '11 at 09:19
5

A little shorter:

def stuff(n, f=None):
  f = f or (lambda x: None)
  f(n)

Or even better:

def stuff(n, f=None):
    f(n) if f is not None else None
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
4

You can't assing empty. But you can creaty internal function, that you will assign to f.

def stuff(n, f=None):
  def empty(n):
    pass
  if f is None:
    f = empty
  f(n)
gruszczy
  • 40,948
  • 31
  • 128
  • 181
3

The generic noop function :

f = lambda *x,**y:None

You can call

f()
f(0,foo=0)
Alcolo47
  • 91
  • 1
  • 4
1

I'd go with a

def nop(*args, **kwargs):
    pass

def algo(func=nop):
    do_something()
    func()
    do_something_else()

algo() # nop is called
algo(some_callback) # some_callback is called

IMHO looks cleaner than

if foo:
    foo()
Ivan Dives
  • 477
  • 5
  • 9