Home > Back-end >  Most Idiomatic Way to Denote Empty Anonymous Function?
Most Idiomatic Way to Denote Empty Anonymous Function?

Time:11-14

In a recent project of mine I encountered a genuine reason to have a parameter, which accepts a function, with a default value.

It looks like this, ignoring the context.

def foo(func: Callable[[], None]) -> None:
    ...

My initial thought was to set the default to lambda: None. Indicating that the default value is a function that accepts no parameters and returns None. i.e.

def foo(func: Callable[[], None] = lambda: None) -> None:
        ...

After some thought I figured lambda: ... would also get that point across, because I found lambda: None to look a bit strange. i.e.

def foo(func: Callable[[], None] = lambda: ...) -> None:
        ...

My question to you is, which of these is better? I am also open to suggestions outside of these two.

Edit: using Callable to type hint the parameter. The second example in fact returns a non-None value, which does not actually matter since in context the return value is not used--however, that is a noteworthy discrepancy.

CodePudding user response:

How about:

from typing import Callable


def foo(func: Callable) -> None:
    ...

See documentation here https://docs.python.org/3/library/typing.html#typing.Callable

Note that there's an important difference between these two examples you provided:

def foo(func: function) -> None:
    ...


def foo(func: function = lambda: ...) -> None:
    ...

In the first case (assuming function is defined, something like Callable, there is no default value and passing a value would be required.

In the second case, the type is the same, but there is a default value and the caller doesn't have to provide one. They make for a very different function.

At any rate, you're really just asking an opinion on style - since you're already using the Ellipsis as an alternative to pass, I feel this is the preferable option:

def foo(func: Callable = lambda: ...) -> None:
    ...

Although this is rather pointless, since your function in this form doesn't even call func, so providing a default parameter value does very little, as the type has already been explicitly specified.

CodePudding user response:

As stated by Grismar you can use Callable as a type hint. But every time you call the function you create a new lambda object so it would behoove you to initialize it outside the function for readability sake and efficiency.

from typing import Callable

default_function = lambda: ...
# or probably better to use
def default_function(...) -> ...:
    ...
    return ...

def foo(func: Callable=default_function) -> None:
    ...
  • Related