`final` keyword equivalent for variables in Python?

后端 未结 11 1946
忘了有多久
忘了有多久 2021-01-30 20:17

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

相关标签:
11条回答
  • 2021-01-30 20:47

    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.

    0 讨论(0)
  • 2021-01-30 20:47

    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
    
    0 讨论(0)
  • 2021-01-30 20:48

    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".

    0 讨论(0)
  • 2021-01-30 20:48

    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.

    0 讨论(0)
  • 2021-01-30 20:48

    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"
    
    0 讨论(0)
提交回复
热议问题