-1

I am not looking for a "physically" immutable member field in Python as I know it is impossible, but just a type annotation to tell type checker that this field should not be re-assign a new value.

For example,


class A:
  def __init__(self, x: int):
    self.x: Annotated[int, Immutable] = x

  def do_something(self):
    self.x = 1   # type checker should be able to report error 

Can I do this in Python? Or are there any better solutions?

link89
  • 1,064
  • 10
  • 13
  • 1
    Does this answer your question? [In Python, how can I make unassignable attributes (like ones marked with \`final\` in Java)?](https://stackoverflow.com/questions/802578/in-python-how-can-i-make-unassignable-attributes-like-ones-marked-with-final) (specifically, [this answer](https://stackoverflow.com/a/58384744)) – SuperStormer Jul 17 '23 at 05:23
  • The question is difference, but the answer is what I am looking for. The question you share is about how to make a variable physically immutable, but what I am looking for is a much weaker solution to just make the type checker to raise error. – link89 Jul 17 '23 at 07:48

2 Answers2

0

Can't post this as a comment due to reputation, but you can make all of the fields immutable through a frozen dataclass or a named tuple. Otherwise, you might be out of luck if you want just a single field to be immutable.

  • Thanks for your suggestion. I am aware of that but they are not what I am looking for. I don't need to a filed to be physically immutable like frozen dataclass or named tuple. But just let the type checker knows the filed should not be reassgin, which should be much more easier to achieve. – link89 Jul 17 '23 at 03:30
0

As mentioned above you can use Final[T]. I personally find class type annotations more readable when defined at the top of the class rather than inside the __init__ that's just preference tho.

cannot assign member x

from typing import Final, TYPE_CHECKING


class A:
    if TYPE_CHECKING:
        x: Final[int]

    def __init__(self, x: int):
        self.x = x

    def do_something(self):
        self.x = 1  # type checker should be able to report error

Another option would be to use a dataclass with the frozen=True and in this case field is actually immutable and will raise an error if modified during runtime.

dataclasses

Jason Leaver
  • 286
  • 2
  • 11