Python 3.5中的类型提示是什么?
Python 3.5中最受关注的特性之一是类型提示 和中提到了类型提示的示例,同时也提到了负责任地使用类型提示。有人能详细解释一下它们,什么时候应该使用,什么时候不应该使用吗?我建议通过打字提示来阅读和观看 简而言之:字体暗示就是这些词的字面意思。提示正在使用的对象的类型 由于Python的动态特性,推断或检查所使用对象的类型尤其困难。这一事实使得开发人员很难理解他们没有编写的代码中到底发生了什么,最重要的是,对于许多IDE中发现的类型检查工具(我也想到了),这些工具由于没有任何对象类型的指示器而受到限制。因此,他们试图推断出(如演示中所述)成功率约为50%的类型Python 3.5中的类型提示是什么?,python,python-3.x,python-3.5,type-hinting,Python,Python 3.x,Python 3.5,Type Hinting,Python 3.5中最受关注的特性之一是类型提示 和中提到了类型提示的示例,同时也提到了负责任地使用类型提示。有人能详细解释一下它们,什么时候应该使用,什么时候不应该使用吗?我建议通过打字提示来阅读和观看 简而言之:字体暗示就是这些词的字面意思。提示正在使用的对象的类型 由于Python的动态特性,推断或检查所使用对象的类型尤其困难。这一事实使得开发人员很难理解他们没有编写的代码中到底发生了什么,最重要的是,对于许多IDE中发现的类型检查工具(我也想到了),这些工具由于没有任何对象类型的指示器
从类型提示演示文稿中选取两张重要幻灯片: 为什么键入提示?
类型错误
,并弹出未为对象定义的方法/属性- 尽早发现bug:我相信这是不言而喻的
- 项目越大,您就越需要它:同样,这是有意义的。静态语言提供了健壮性和 缺乏动态语言。应用程序越大、越复杂,控制和可预测性就越强(从 行为方面)你需要的
- 大型团队已经在运行静态分析了:我猜这验证了前两点
用mypy键入提示: 为了使这个答案更完整,我认为进行一点演示是合适的。我将使用一个库,它激发了PEP中显示的类型提示。这本书主要是写给任何碰到这个问题并想知道从哪里开始的人的 在此之前,让我重申以下几点:不强制执行任何内容;它只是为功能设定一个方向 注释和建议如何执行类型检查的指南。您可以注释您的函数和 你想暗示多少就暗示多少;无论是否存在注释,脚本仍将运行,因为Python本身不使用注释 无论如何,正如政治公众人物中所述,暗示类型通常应采取三种形式:
- 函数注释()
- 内置/用户模块的存根文件
- 特殊的
#类型:输入补充前两种形式的注释。(请参阅:,了解有关
注释的Python 3.6更新)#type:type
Py3.5
中引入的新模块结合使用。在它中,定义了许多(附加的)(抽象基类)以及用于静态检查的辅助函数和装饰器。集合中的大多数abc.abc
都包含在内,但为了允许订阅(通过定义\uuuu getitem\uuuuuuuuuuuuuuo()
方法),它们是以通用形式存在的
对于任何对更深入的解释感兴趣的人来说,编写得非常好,并且有很多代码示例演示/描述其检查器的功能;这绝对值得一读
功能注释和特殊注释:
首先,观察我们在使用特殊注释时的一些行为是很有趣的。特殊#类型:类型
注释
如果无法直接推断对象的类型,则可以在变量指定期间添加,以指示对象的类型。简单的作业是
通常很容易推断,但其他的,如列表(就其内容而言),则不能
注意:如果我们想使用容器的任何衍生工具,并且需要指定该容器的内容,我们必须使用键入模块中的通用类型这些支持索引。
# Generic List, supports indexing.
from typing import List
# In this case, the type is easily inferred as type: int.
i = 0
# Even though the type can be inferred as of type list
# there is no way to know the contents of this list.
# By using type: List[str] we indicate we want to use a list of strings.
a = [] # type: List[str]
# Appending an int to our list
# is statically not correct.
a.append(i)
# Appending a string is fine.
a.append("i")
print(a) # [0, 'i']
如果我们将这些命令添加到一个文件中,并使用解释器执行它们,那么一切都会正常工作,并且打印(a)
只打印
列表a
的内容。#type
注释已被丢弃,被视为没有附加语义的普通注释
另一方面,通过使用mypy
,我们得到以下响应:
(Python3)jimmi@jim: mypy typeHintsCode.py
typesInline.py:14: error: Argument 1 to "append" of "list" has incompatible type "int"; expected "str"
表示str
对象的列表不能包含int
,静态地说,它是正确的。这可能是金融机构
def annotated(x: int, y: str) -> bool:
return x < y
{'y': <class 'str'>, 'return': <class 'bool'>, 'x': <class 'int'>}
(Python3)jimmi@jim: mypy typeHintsCode.py
typeFunction.py: note: In function "annotated":
typeFunction.py:2: error: Unsupported operand types for > ("str" and "int")
annotated(20, 20)
# mypy complains:
typeHintsCode.py:4: error: Argument 2 to "annotated" has incompatible type "int"; expected "str"
def message(s):
print(s)
def alterContents(myIterable):
return [i for i in myIterable if i % 2 == 0]
def combine(messageFunc, itFunc):
messageFunc("Printing the Iterable")
a = alterContents(range(1, 20))
return set(a)
# Stub for randfucn.py
from typing import Iterable, List, Set, Callable
def message(s: str) -> None: pass
def alterContents(myIterable: Iterable[int])-> List[int]: pass
def combine(
messageFunc: Callable[[str], Any],
itFunc: Callable[[Iterable[int]], List[int]]
)-> Set[int]: pass
class Counter(Dict[_T, int], Generic[_T]):
@overload
def __init__(self) -> None: ...
@overload
def __init__(self, Mapping: Mapping[_T, int]) -> None: ...
@overload
def __init__(self, iterable: Iterable[_T]) -> None: ...
def greeting(name: str) -> str:
return 'Hello ' + name
class C1:
def __init__(self):
self.idn = 1
def add(self, ic: int):
return self.idn + ic
c1 = C1()
c1.add(2)
c1.add(c1)