Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type hint variable that is initially None but is guaranteed to get a value

I have a class variable as shown below:

class MyClass:
    def __init__(self):
        self.value: MyOtherClass | None = None
        self.initialize_value()

    def initialize_value(self):
        self.value = MyOtherClass()

    def use_value(self):
        return self.value.used

self.value is guaranteed to be initialized as an instance of MyOtherClass before being used in self.use_value(); however, it must remain as None in the constructor. The dilemma here is how to properly typehint this situation.

  • If I choose to typehint it as shown above, I get an error: Item "None" of "Optional[MyOtherClass]" has no attribute "used" [union-attr]
  • If I instead remove the variable definition from the constructor and move the typehint to self.initialize_value(), I get an Instance attribute value defined outside __init__ error from Pylint

What is the best way to go about this? Thanks a lot!

like image 510
Krishnan Shankar Avatar asked Jan 18 '26 16:01

Krishnan Shankar


1 Answers

To avoid repetition, when such an attribute is used throughout the class in multiple methods, a common pattern for me is protecting it and defining a property that raises an error, if the attribute behind it is not set:

class MyClass:
    def __init__(self):
        self._value: MyOtherClass | None = None
        self.initialize_value()

    @property
    def value(self) -> MyOtherClass:
        if self._value is None:
            raise AttributeError("...")
        return self._value

    def initialize_value(self):
        self._value = MyOtherClass()

    def use_value(self):
        return self.value.used

This also removes ambiguity for the type checker since the return type of the property is always MyOtherClass.

like image 140
Daniil Fajnberg Avatar answered Jan 20 '26 04:01

Daniil Fajnberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!