I couldn\'t find documentation on an equivalent of Java\'s final
in Python, is there such a thing?
I\'m creating a snapshot of an object (used for restorati
Python 3.8 (via PEP 591) adds Final
variables, functions, methods and classes. Here are some ways to use it:
@final
Decorator (classes, methods)
from typing import final
@final
class Base:
# Cannot inherit from Base
class Base:
@final
def foo(self):
# Cannot override foo in subclass
Final
annotation
from typing import Final
PI: Final[float] = 3.14159 # Cannot set PI to another value
KM_IN_MILES: Final = 0.621371 # Type annotation is optional
class Foo:
def __init__(self):
self.bar: Final = "baz" # Final instance attributes only allowed in __init__
Please note that like other typing hints, these do not prevent you from overriding the types, but they do help linters or IDEs warn you about incorrect type usage.
you can simulate something like that through the descriptor protocol, since it allows to define reading and setting a variable the way you wish.
class Foo(object):
@property
def myvar(self):
# return value here
@myvar.setter
def myvar(self, newvalue):
# do nothing if some condition is met
a = Foo()
print a.myvar
a.myvar = 5 # does nothing if you don't want to
Python has no equivalent of "final". It doesn't have "public" and "protected" either, except by naming convention. It's not that "bondage and discipline".
As of 2019 and PEP 591, Python has a Final
type. It won't be available in the standard library until the release of Python 3.8, but until then you can use it via the typing-extensions library. It won't work as final
works in Java though as Python is still a dynamically typed language. But if you use it together with a static type checker like mypy it will give you very similar benefits.
There is also a final
decorator that can be applied to mark class methods as final and preventing from being overridden. Again this is only checked at "compile-time", so you'd need to include a static type checker in your workflow.
Python indeed does not have a final type, it does have immutable types such as tuples but that is something else.
Some of the other Answers here make classes full of pseudo final variables and I prefer my class to only have a few Final types, so I suggest using an descriptor to create the final type:
from typing import TypeVar, Generic, Type
T = TypeVar('T')
class FinalProperty(Generic[T]):
def __init__(self, value: T):
self.__value = value
def __get__(self, instance: Type, owner) -> T:
return self.__value
def __set__(self, instance: Type, value: T) -> None:
raise ValueError("Final types can't be set")
If you use this class like so:
class SomeJob:
FAILED = FinalProperty[str]("Failed")
Then you will not be able to set that variable in any instance of that class. Unfortunately as with the WriteOnceReadWhenever answer you can still set the class variable.
job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"