How do I add default parameters to functions when using type hinting?
Your second way is correct.
def foo(opts: dict = {}):
pass
print(foo.__annotations__)
this outputs{'opts': <class 'dict'>}
It's true that's it's not listed in PEP 484, but type hints are an application of function annotations, which are documented in PEP 3107. The syntax section makes it clear that keyword arguments works with function annotations in this way. I strongly advise against using mutable keyword arguments. More information here.
Type Hinting: Default Parameters
You can't typehint strings, you can only typehint objects and arrays, so this is incorrect:
function setName ( string $name = "happ") {
(The reason you don't get a compile-time error here is because PHP is interpreting "string" as the name of a class.)The wording in the docs means that if you do this:
function foo(Foo $arg) {
Then the argument passed to foo() must be an instance of object Foo. But if you do this:function foo(Foo $arg = null) {
Then the argument passed to foo() can either be an instance of object Foo, or null. Note also that if you do this:function foo(array $foo = array(1, 2, 3))
Then you can't call foo(null). If you want this functionality, you can do something like this:function foo(array $foo = null) {
if ($foo === null) {
$foo = array(1, 2, 3);
}
[Edit 1]
As of PHP 5.4, you can typehint callable
:function foo(callable $callback) {
call_user_func($callback);
}
[Edit 2]
As of PHP 7.0, you can typehint bool
, float
, int
, and string
. This makes the code in the question valid syntax. As of PHP 7.1, you can typehint iterable
. How to type hint function with a callable argument and default value
You could use the @overload for correctly type hinting of function with default argument for your case:
from typing import Callable, List, TypeVar, overload, Set
T = TypeVar("T")
@overload
def transform(data: List[int]) -> Set[int]: ...
@overload
def transform(data: List[int], ret_type: Callable[[List[int]], T]) -> T: ...
# untyped implementation
def transform(data, ret_type = set):
return ret_type(data)
a = [1, 2, 3]
my_set: Set = transform(a)
How to type hint a Callable of a function with default arguments?
Define this:
class Foo(Protocol):
def __call__(self, x: int = ..., /) -> float:
...
then type hint foo
as Foo
instead of Callable[[int], float]
. Callback protocols allow you to:define flexible callback types that are hard (or even impossible) to express using the Callable[...]
syntax
and optional arguments are one of those impossible things to express with a normal Callable
. The /
at the end of __call__
's signature makes x
a positional-only parameter, which allows any passed function to bar
to have a parameter name that is not x
(your specific example of foo
calls it arg
instead). If you removed /
, then not only would the types have to line up as expected, but the names would have to line up too because you would be implying that Foo
could be called with a keyword argument. Because bar
doesn't call foo
with keyword arguments, opting into that behavior by omitting the /
imposes inflexibility on the user of bar
(and would make your current example still fail because "arg" != "x"
). Type-hinting parameters with a sentinel value as the default
Something I like to do — which is only a slight variation on @Blckknght's answer — is to use a metaclass to give my sentinel class a nicer repr and make it always-falsey.
sentinel.py
from typing import Literal
class SentinelMeta(type):
def __repr__(cls) -> str:
return f'<{cls.__name__}>'
def __bool__(cls) -> Literal[False]:
return False
class Sentinel(metaclass=SentinelMeta): pass
main.pyfrom sentinel import Sentinel
class DEFAULT(Sentinel): pass
You use it in type hints exactly in the same way @Blckknght suggests:
def spam(ham: list[str]|None|type[DEFAULT] = DEFAULT): ...
But you have the added advantages that your sentinel value is always falsey and has a nicer repr:>>> DEFAULT
<DEFAULT>
>>> bool(DEFAULT)
False
Related Topics
Get Query Back from Pdo Prepared Statement
Converting Nsarray -> JSON -> Nsdata -> PHP Server ->JSON Representation
Pdo_Sqlite Driver Not Present.. What to Do
Cannot Unpack Array with String Keys
No Hint Path Defined for [Mail] Laravel 5.4
How to Encrypt HTML Source Code Output Using PHP
Pass Array to Where in Codeigniter Active Record
"Call to Undefined Function" Error When Calling Class Method
How to Get the Session Id in Laravel
Call to Undefined Function Curl_Init() - with Wamp
How to Display HTML to the Browser Incrementally Over a Long Period of Time
How to Sort an Array by Similarity in Relation to an Inputted Word
Php, How to Get Current Date in Certain Format
Newline Not Working in PHP Mail
Built in Support for Sets in PHP
Doctrine 2 Lifecyclecallbacks with Abstract Base Class Are Not Called