1 分钟了解 Python 中的实数常量
许多语言都喜欢java
并php
共享实体的概念final
。final
实体是无法改变的东西。
我们在 中没有这个功能python
。直到最近发生了两件事:
- 我已经发布了
final-class
包 python
核心团队已发布模块的官方final
支持typing
现在我们真的拥有了一个闪亮的新语言特性!让我们深入了解它的工作原理以及它为何如此出色。
声明常量
首先,您需要mypy
安装type_extensions
:
» pip install mypy typing_extensions
然后我们就可以开始使用它了:
from typing_extensions import Final
DAYS_IN_A_WEEK: Final = 7
就是这样!但是,如果我们尝试修改这个常量,会发生什么呢?
from typing_extensions import Final
DAYS_IN_A_WEEK: Final = 7
DAYS_IN_A_WEEK = 8 # I really want more days in a week!
真的,没什么。这只是个老套的玩意儿python
,你可以用它来做一些稀奇古怪的事情,而且没有任何回报。它根本不关心类型注解。
只有当我们运行类型检查器时,所有的魔法才会发生mypy
:
» mypy --python-version=3.6 --strict week.py
week.py:4: error: Cannot assign to final name "DAYS_IN_A_WEEK"
轰!我们这里有一个常数!
看看Final
type 如何处理底层类型。你无需手动告诉类型检查器实际类型是什么。它会自行判断。换句话说,类型检查器会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}
现在,这个假想类的所有子类都无法重新定义namespace
和resolve()
。不过,我们来尝试一下 hack 一下,看看会发生什么:
class ConcreteAPI(BaseAPIDeclaration):
namespace = 'custom-api'
def resolve(self) -> dict:
return {'hacking': True}
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")
课程
甚至类也可以final
。这样,我们可以明确禁止对没有设计为子类的类进行子类化:
from typing_extensions import final
@final
class HRBusinessUnit(AbstractBusinessUnit):
def grant_permissions(self) -> None:
self.api.do_some_hr_stuff()
装饰器能给你带来什么@final
?自信地相信没有什么可以破坏这个契约:
class SubHRBusinessUnit(HRBusinessUnit):
def grant_permissions(self) -> None:
self.api.do_some_it_stuff()
此代码会让人mypy
很不高兴(请不要滥用机器人!):
» mypy --python-version=3.6 --strict units.py
units.py:9: error: Cannot inherit from final class "HRBusinessUnit"
现在我们可以解释为什么你应该在你的项目中使用它。
结论
创建新的限制对您有好处:它使您的代码更清晰、更易读,并提高其质量。
优点:
- 从定义中可以清楚地看出什么是常数或具体实现,什么不是
- 我们的用户将拥有严格的 API 边界,不得违反
- 我们可以建立不容忍违反规则的封闭系统
- 更容易理解应用程序内部发生的事情
- 它强制执行组合而不是继承,这是一个众所周知的最佳实践
缺点:没有!如果你发现任何缺点,请留言。
使用类型,创建良好的 API,继续黑客攻击!
鏂囩珷鏉ユ簮锛�https://dev.to/wemake-services/1-minute-guide-to-real-constants-in-python-2bpk