随着Python 3.8即将发布,只是想知道The Final decorator和The Final annotation之间的区别。
在 Python3.8 中,Python 类型提示功能(由typing
模块体现(将支持将名称标记为final。这记录在 PEP 591 –向键入添加最终限定符中。
这意味着typing
模块获得了两个新对象:
typing.Final
类型构造@typing.final()
装饰器。
坦率地说:Python语言本身不会获得final
语法或支持。上述对象不会改变 Python 的工作方式,它们是仅记录对象或引用被视为最终对象的构造。新对象可以简单地向后移植到较旧的 Python 版本。typing-extensions
项目提供了从更高到早期 Python 版本的typing
功能的向后移植,已经包含了这些对象。
它们的用途在于使用像mypy这样的类型提示检查器来检查您的项目是否正确地将记录为最终的对象。
它们的用法与 Java 中的final
关键字完全相同:声明特定引用只能分配给一次,方法不能在子类中被覆盖,或者类定义不能被子类化。
使用
typing.Final
对象将全局或属性标记为 final,并记录该值在分配给以下位置后永远不会更改:GLOBAL_CONSTANT: Final[str] = "This is a constant value because it is final"
使用
@typing.final
装饰器将方法标记为不可重写(子类不能定义不同的实现(或将类标记为不可继承(不能从类创建子类(:@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"""
另请参阅有关其使用的 mypy 文档,其中涵盖了哪些分配Final
属性值的方法是可接受的详细信息。
演示:
$ 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")