How should I use the Optional type hint in Python?
I am trying to understand how to use the Optional type hint. According to PEP-484, I know that Optional can be used for a function like def test(a: int = None), which is equivalent to def test(a: Union[int, None]) or def test(a: Optional[int]).
But how should I handle cases like the following examples?
def test(a: dict = None):
#print(a) ==> {'a': 1234}
#or
#print(a) ==> None
def test(a: list = None):
#print(a) ==> [1, 2, 3, 4, 'a', 'b']
#or
#print(a) ==> None
Since Optional[type]
seems to mean the same thing as Union[type, None]
, why should I use Optional[]
at all? How does Python optional differ from using Union in these cases?
Understanding Optional as a shorthand for Union: The Optional[type
] is just a shorthand for Union[type, None].
While both indicate that a value could either be of the specified type or None, Optional is preferred for readability and clarity. In the case of functions like def test(a: dict = None)
or def test(a: list = None)
, you could explicitly write them as def test(a: Optional[dict] = None)
or def test(a: Optional[list] = None).
This makes the intention clear: a could either be a dict/list or None.
If you expect the parameter to always be a specific type and None is not intended as a valid value (other than for default initialization), avoid using Optional.
For example, def test(a: dict) (without Optional)
is better when a must be a dictionary and can be None, whereas def test(a: Optional[dict] = None)
is suitable if None is a valid default or expected value.
When a function has default None values, and you want to indicate that a parameter could be of a specific type or None, Optional is appropriate.
For instance, def test(a: Optional[dict] = None)
is more explicit and communicates that a can be a dictionary or None, which matches the default behavior of using None as a placeholder. This provides clarity over using Union directly.