Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

final annotation and decorator in python3.8

As Python 3.8 releasing soon just wanted to know the difference between The final decorator and The Final annotation.

like image 594
Roushan Avatar asked Dec 11 '25 22:12

Roushan


1 Answers

In Python 3.8 the Python type hinting feature (embodied by the typing module) will support marking names as final. This is documented in PEP 591 – Adding a final qualifier to typing.

What this means is that the typing module gains two new objects:

  • The typing.Final typing construct
  • The @typing.final() decorator.

To be up-front: The Python language itself does not gain final syntax or support. The above objects do not alter how Python works, they are constructs that merely document that an object or reference is to be considered final. The new objects can trivially be backported to older Python releases. The typing-extensions project, which provides backports of typing features from later to earlier Python versions, has already included these objects.

Their use lies in using a type hint checker like mypy to check that your project correctly treats the objects so documented as final.

Their use is otherwise exactly like that of the final keyword in Java: to state that a specific reference can only be assigned to once, that a method cannot be overridden in a subclass, or that a class definition cannot be subclassed.

  • Use the typing.Final object to mark a global or attribute as final, documenting that the value will never change once assigned to:

      GLOBAL_CONSTANT: Final[str] = "This is a constant value because it is final"
    
  • Use the @typing.final decorator to mark a method as non-overridable (subclasses can't define a different implementation) or a class as non-inheritable (you can't create subclasses from the class):

      @final
      class FinalClass:
          """This class can't be inherited from"""
    
      class SomeClass:
          @final
          def final_method(self):
              """Subclasses can't define a different final_method implementation"""
    

Also see the mypy documentation on their use, which covers such details as to what ways of assigning the value of a Final attribute are acceptable.

Demo:

$ cat demo.py
from typing import final, Final

# FOO is marked final, can't assign another value to it
FOO: Final[int] = 42

class Foo:
    @final
    def spam(self) -> int:
        """A final method can't be overridden in a subclass"""
        return 42

@final
class Bar:
    """A final class can't be subclassed"""

# Rule breaking section
FOO = 81

class Spam(Foo, Bar):
    def spam(self) -> int:
        return 17

if __name__ == '__main__':
    print("FOO:", FOO)
    print("Spam().spam():", Spam().spam())

$ python3.8 demo.py   # Python will not throw errors here
FOO: 81
Spam().spam(): 17
$ mypy demo.py        # only a type checker will
demo.py:17: error: Cannot assign to final name "FOO"
demo.py:19: error: Cannot inherit from final class "Bar"
demo.py:20: error: Cannot override final attribute "spam" (previously declared in base class "Foo")
like image 173
Martijn Pieters Avatar answered Dec 14 '25 11:12

Martijn Pieters