I've been reading through PEP484 and 526 and still can't figure out what is a better way to do type annotations for variables without an initial value.
Say, you have a class and in the __init__
you want to declare a variable, but without providing an initial value where assignment happens later in the code. Usually what I would normally do is:
from typing import Optional, List
class SomeClass:
def __init__(self) -> None:
self.some_value: Optional[int] = None
self.other_var: Optional[List] = None
def _some_method(self) -> None:
self.some_value = 42
This works, but I feel like using Optional makes __init__
overly busy and harder to read. Instead what I could do is:
from typing import List
class SomeClass:
def __init__(self) -> None:
self.some_value: int
self.other_var: List
def _some_method(self) -> None:
self.some_value = 42
Obviously, this leaves variables uninitialized, but as long as they are correctly assigned to before being referenced, everything works just fine and makes it easier to read if I have a lot of class attributes declared in __init__
.
Are there any specific issues that could arise from leaving variables uninitialized when using the second approach?
Yes. Adding type annotations without setting a value is for the type checker only. You won't actually create the variable. Just have a look at the error thrown from your second example:
Note that the error is "has no attribute". In other words, the attribute was not created at all.
As of Python 3.10 the syntax has gotten a little cleaner, so you don't need the import from
typing
anymore, and you don't needOptional
anymore. This is how I'd type your class: