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:
...