1 分钟了解 Python 中的实数常量

2025-06-10

1 分钟了解 Python 中的实数常量

许多语言都喜欢javaphp共享实体的概念final
final实体是无法改变的东西。

我们在 中没有这个功能python。直到最近发生了两件事:

  1. 我已经发布了final-class
  2. python核心团队已发布模块的官方final支持typing

现在我们真的拥有了一个闪亮的新语言特性!让我们深入了解它的工作原理以及它为何如此出色。

声明常量

首先,您需要mypy安装type_extensions

» pip install mypy typing_extensions
Enter fullscreen mode Exit fullscreen mode

然后我们就可以开始使用它了:

from typing_extensions import Final

DAYS_IN_A_WEEK: Final = 7
Enter fullscreen mode Exit fullscreen mode

就是这样!但是,如果我们尝试修改这个常量,会发生什么呢?

from typing_extensions import Final

DAYS_IN_A_WEEK: Final = 7
DAYS_IN_A_WEEK = 8  # I really want more days in a week!
Enter fullscreen mode Exit fullscreen mode

真的,没什么。这只是个老套的玩意儿python,你可以用它来做一些稀奇古怪的事情,而且没有任何回报。它根本不关心类型注解。

只有当我们运行类型检查器时,所有的魔法才会发生mypy

» mypy --python-version=3.6 --strict week.py
week.py:4: error: Cannot assign to final name "DAYS_IN_A_WEEK"
Enter fullscreen mode Exit fullscreen mode

轰!我们这里有一个常数!

看看Finaltype 如何处理底层类型。你无需手动告诉类型检查器实际类型是什么。它会自行判断。换句话说,类型检查器会DAYS_IN_A_WEEK知道int

接口

它不仅仅是声明常量。你可以声明接口部分,例如不应更改的属性和方法:

from typing_extensions import Final, final

class BaseAPIDeclaration(object):
     namespace: Final = 'api'

     @final
     def resolve(self) -> dict:
         return {'namespace': self.namespace, 'base': True}
Enter fullscreen mode Exit fullscreen mode

现在,这个假想类的所有子类都无法重新定义namespaceresolve()。不过,我们来尝试一下 hack 一下,看看会发生什么:

class ConcreteAPI(BaseAPIDeclaration):
    namespace = 'custom-api'

    def resolve(self) -> dict:
        return {'hacking': True}
Enter fullscreen mode Exit fullscreen mode

mypy将会支持我们。输出如下所示:

» mypy --python-version=3.6 --strict api.py
api.py:12: error: Cannot assign to final name "namespace"
api.py:14: error: Cannot override final attribute "resolve" (previously declared in base class "BaseAPIDeclaration")
Enter fullscreen mode Exit fullscreen mode

课程

甚至类也可以final。这样,我们可以明确禁止对没有设计为子类的类进行子类化:

from typing_extensions import final

@final
class HRBusinessUnit(AbstractBusinessUnit):
    def grant_permissions(self) -> None:
        self.api.do_some_hr_stuff()
Enter fullscreen mode Exit fullscreen mode

装饰器能给你带来什么@final?自信地相信没有什么可以破坏这个契约:

class SubHRBusinessUnit(HRBusinessUnit):
    def grant_permissions(self) -> None:
        self.api.do_some_it_stuff()
Enter fullscreen mode Exit fullscreen mode

此代码会让人mypy很不高兴(请不要滥用机器人!):

» mypy --python-version=3.6 --strict units.py
units.py:9: error: Cannot inherit from final class "HRBusinessUnit"
Enter fullscreen mode Exit fullscreen mode

现在我们可以解释为什么你应该在你的项目中使用它。

结论

创建新的限制对您有好处:它使您的代码更清晰、更易读,并提高其质量。

优点:

  1. 从定义中可以清楚地看出什么是常数或具体实现,什么不是
  2. 我们的用户将拥有严格的 API 边界,不得违反
  3. 我们可以建立不容忍违反规则的封闭系​​统
  4. 更容易理解应用程序内部发生的事情
  5. 它强制执行组合而不是继承,这是一个众所周知的最佳实践

缺点:没有!如果你发现任何缺点,请留言。

使用类型,创建良好的 API,继续黑客攻击!

鏂囩珷鏉ユ簮锛�https://dev.to/wemake-services/1-minute-guide-to-real-constants-in-python-2bpk
PREV
在 Python 中实施单一职责原则
NEXT
使用 asyncio 在 Python 中进行异步编程 并发 vs 并行 为什么使用 asyncio 如何在 Python 中编写异步代码 异步函数 真实示例 异步生成器 异常处理 深入了解