Cap*_*ero 13 python types type-hinting
在 Python 的输入和类型提示文档中,我们有以下示例:
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
Run Code Online (Sandbox Code Playgroud)
Vector
类型别名清楚地表明类型别名对于简化复杂的类型签名很有用。
然而,给原始数据类型别名又如何呢?
让我们对比两个函数签名的基本示例:
URL = str
def process_url(url: URL) -> URL:
pass
Run Code Online (Sandbox Code Playgroud)
对比
def process_url(url: str) -> str:
pass
Run Code Online (Sandbox Code Playgroud)
URL
原始类型具有类型别名的版本str
是:
Dict
或namedtuple
稍后)。问题是我找不到其他人遵循这种做法。我只是担心我无意中滥用类型提示来实现我自己的想法,而不是遵循它们的预期目的。
2020-10 年注意事项
Python 3.9 引入了“灵活的函数和变量注释”,它允许进行如下注释:
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
Run Code Online (Sandbox Code Playgroud)
这使得用于文档目的的别名数据类型相当多余!
看:
Mis*_*agi 17
使用别名来标记值的含义可能会产生误导和危险。如果只有一部分值有效,则应改用NewType。
回想一下,类型别名的使用将两种类型声明为彼此等效。这样做
Alias = Original
将会使静态类型检查治疗Alias
为完全等同于Original
在所有情况下。当您想要简化复杂的类型签名时,这很有用。
简单的别名有两种作用:别名URL = str
意味着 anyURL
是 a str
,也意味着anystr
是URL
a——这通常是不正确的:URL 是一种特殊的类型,str
没有任何可以取代它的位置。别名URL = str
是一种过于强烈的平等声明,因为它无法表达这种区别。其实任何不看源码的检查都看不出区别:
In [1]: URL = str
In [2]: def foo(bar: URL):
...: pass
...:
In [3]: foo?
Signature: foo(bar: str)
Run Code Online (Sandbox Code Playgroud)
考虑Celsius = float
在一个模块和Fahrenheit = float
另一个模块中使用别名。这表明使用Celsius
as是有效的Fahrenheit
,这是错误的。
除非你的类型做卡里分离式的意义,你应该采取url: str
。名称表示含义,类型表示有效值。这意味着您的类型应该适合分隔有效值和无效值!
使用别名来缩短你的提示,但使用 NewType 来细化它们。
Vector = List[float] # alias shortens
URL = NewType("URL", str) # new type separates
Run Code Online (Sandbox Code Playgroud)
我不确定这个问题是否基于意见,但我有一种感觉,总的来说,这是一个好主意。您自己陈述了好处,更不用说概括代码的能力等。
我敢说这在 Python 中并不常见,因为该语言本身的限制并不多。此外,该变量已经被调用url
——这是非常不言自明的。你可能会争辩说你可能有一个叫json_response
或类似的东西,你希望它是一个url
,你的方法肯定会清楚地表明这一点,但由于Python鼓励鸭子类型,代码使用通常会给出这个提示,无论如何,使用类型别名会对于不体贴的用户来说只是额外的安全。这实际上只是常见的做法,没有好的“这样做!” 解释。
从某种意义上说,最终的点类型别名是面向对象编程的最原始版本。您正在明确您期望该对象具有哪些属性,在本例中,字符串应该是有效的 URL。
归档时间: |
|
查看次数: |
1787 次 |
最近记录: |