snazzybouche
snazzybouche

Reputation: 2426

How to use a lambda as a default argument?

I'm trying to make a function that will take an optional parameter, callback, which must be a function.

I'd like the default value for this function to be nothing - i.e. a function that does nothing. The way that seems to make sense to me is:

do_the_thing()
do_the_thing(callback = print) # or message.respond, or log_to_file, etc

def do_the_thing(**kwargs):
    cb = kwargs.get('callback', lambda x: pass)
    # do things
    cb("Things have been done.")

But I get a syntax error at the end of "pass".

What's the correct way to go about this?

Upvotes: 4

Views: 3414

Answers (1)

MSeifert
MSeifert

Reputation: 152667

Pythons lambda are more restricted than normal def functions. Typically lambda requires an expression in the body ... but pass is just a statement. So the obvious solution would be to use:

lambda x: None  # or since you don't use x "lambda _: None"

As a rule of thumb: everything that can be assigned to a variable can also be in the body of a lambda. You can find out more about the grammar in the The Python Language Reference

6.13. Lambdas

lambda_expr        ::=  "lambda" [parameter_list] ":" expression
lambda_expr_nocond ::=  "lambda" [parameter_list] ":" expression_nocond

and similar for pass

7. Simple statements

simple_stmt ::=  expression_stmt
[...]
                 | pass_stmt
[...]

pass_stmt ::=  "pass"

Or in the more formal Full Grammar specification. Here you can use any test for assignment and lambda bodies, and a test can be an expr. Here is a (severly) shorted part:

pass_stmt: 'pass'

annassign: ':' test ['=' test]
lambdef: 'lambda' [varargslist] ':' test

test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*

Upvotes: 5

Related Questions