Your second way is correct.
def foo(opts: dict = {}):
pass
print(foo.__annotations__)
this outputs
{'opts': <class 'dict'>}
Although it is not explicitly mentioned in PEP 484, type hints are a specific use of function annotations, as outlined in PEP 3107. The syntax section clearly demonstrates that keyword arguments can be annotated in this manner.
I strongly advise against using mutable keyword arguments. More information here.
Answer from noɥʇʎԀʎzɐɹƆ on Stack OverflowYour second way is correct.
def foo(opts: dict = {}):
pass
print(foo.__annotations__)
this outputs
{'opts': <class 'dict'>}
Although it is not explicitly mentioned in PEP 484, type hints are a specific use of function annotations, as outlined in PEP 3107. The syntax section clearly demonstrates that keyword arguments can be annotated in this manner.
I strongly advise against using mutable keyword arguments. More information here.
If you're using typing (introduced in Python 3.5) you can use typing.Optional, where Optional[X] is equivalent to Union[X, None]. It is used to signal that the explicit value of None is allowed . From typing.Optional:
def foo(arg: Optional[int] = None) -> None:
...
With Python 3.10 and above, as mentioned in joel's comment, this can equivalently be written as:
def foo(arg: int | None = None) -> None:
...
You can't really specify it directly in the argument field, but you can convert it right after the function declaration:
def profile(request, pk=0):
pk = int(pk)
#to do
It will throw an error if the passed value for pk cannot be converted to an int
EDIT: I spoke too soon, apparently you can do exactly as you did, just change things around:
def profile(request, pk: int = 0):
#to do
BTW: I just did a quick research for "specify type of argument python". Please try to research easy things like so first before asking a question, you'll get an answer quicker :)
My code works for any input type of pk: integer, string with integer, string without integer
import re
def intCheck(pk):
contains_number = bool(re.search(r'\d', pk))
if contains_number:
return int(re.search(r'\d+', pk).group())
else:
return 0
def profile(request, pk=0):
pk = intCheck(pk)
print(request + " " + str(pk))
profile('request', "232")
profile('request', 123)
profile('request', "no number")
Output:
request 232
request 123
request 0
Can I define both function's argument's default value and data type in python? - Stack Overflow
Type hinting weirdness with "None" as default value when I need to default to class' initial value or get a value from user
Python Function Default Values
Today I re-learned: Python function default arguments are retained between executions
Sorry for the confusing title.
I have been adding some type hinting into my code and noticed that if I have something like:
def create(self, a: int = None) -> None a = a or self.a
Where I would like to have the user either give a as an int or just skip it and the function will default to the class' initial value for a. This works just fine but this shows in the IDE as create(self, a: int | None = None) -> None which looks like None is a valid value for a, even though that is not what I am looking for.
Then if I have an artificial case like:
def create(self, a: int = 'test') -> None ...
Which then shows up as create(self, a: int = 'test') -> None which looks weird but at least it doesn't explicitly imply that str is a valid parameter.
So I guess two questions: what makes None special? And, is this the way to use type hinting when I need to default to class' initial value or get an argument from user?
Say I have a function defined like
def f(foo: str, bar: str | None = "world"):
print(f"{foo} {bar})
s = None
f("hello") # prints "hello world"
f("hello", s) # prints "hello None"
Is there a data type (or concept) in Python that would enable the second function call to print "hello world" as well? In other words, bar should take on its default value. In javascript, passing undefined for bar would accomplish this. In Python, it seems like I would have to add a conditional to the function.
def f(foo: str, bar: str | None = "world"):
bar = bar or "world"
print(f"{foo} {bar})This isn't a major issue for me, but when a function has a lot of optional arguments with default values, it can be pretty verbose (for Python standards) to add a conditional for every optional argument.