3

众所周知,当我们使用 Python 这样的动态语言时,我们不必担心 Types。因为动态类型让我们无需担心。即便如此,我们可以使用函数type()(在 Python 中)知道变量的类型。所以我的问题是:动态语言中的类型检查有什么好处?

4

3 回答 3

8

在某些情况下,您想要进行类型检查。比如说,你想使用迭代器,而不是字符串——这是一个很常见的情况。进行该检查的最佳方法是键入检查项目是否为字符串:

if isinstance(someobj, str):  # basestring in 2.x
    ...

我们使用isinstance()它,因为它允许子类以及类本身的实例。直接使用检查type()几乎是一个普遍的糟糕想法,但type()确实有其他用途 - 有时您出于类型检查以外的原因想要访问实例的类。

还值得注意的是,Python 允许使用子类挂钩定义抽象基类isinstance()- 这允许进行一种鸭子类型检查,其中检查类是否有所需的相关方法。例如,如果你想检查某个东西是一个序列,那么做isinstance(obj, collections.Sequence)不错,因为它实际上不是传统意义上的类型检查,它会检查对象是否具有序列接口所需的功能(如docs中所定义) .

然而,一般来说,应该避免类型检查。在大多数情况下,可以简单地尝试做你想做的事,然后在对象不能做它需要做的事情时捕获异常。Python 通常遵循请求原谅而不是许可的规则,因此请尝试并优雅地处理错误,而不是事前检查。

简而言之:在动态语言中,我们依赖于鸭式打字。如果一个物体可以嘎嘎叫,我们可以假设它是一只鸭子。99% 的情况下,可以嘎嘎叫的物体都可以被视为鸭子,所以我们没问题。但是,在极少数情况下,不应将另一种会叫的动物视为鸭子。我们可以区分它们的唯一方法是键入检查,这没关系。但是,类型检查不应该用于检查我们的动物是否会嘎嘎,因为我们可以尝试看看(或者,如果我们现在不能让它嘎嘎,但仍然需要依赖它进行操作,请直接检查嘎嘎的能力,而不是检查我们知道可以嘎嘎的类型)。

于 2013-05-06T20:42:48.937 回答
1

在 python 中,一切都是“对象”,并继承了一些赋予它独特性的“属性”和“方法”。

因此,类型是对象根据“方法”和“属性”对它进行表征的“分类”。换句话说,类型检查在“方法”和“属性”方面为我们提供了该对象的效用。

python“列表”是一个序列,一个python“字符串”是一个序列,但它们具有不同的属性(一个可变的和其他不可变的),因此它们具有操纵其结构的独特方法。例如列表可以使用'append'和'pop'来增加或减少大小,对于字符串它们是被禁止的。对于可能不起作用的列表,字符串的表示可能会随着“大写”或“更低”而改变。

>>> i = ""  # i declared string here
>>> i.append("K")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'append'
>>> i.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'pop'

相似地,

>>> a = [] # a declared a list here
>>> a.lower()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'lower'
>>> a.capitalize()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'capitalize'

谢谢阅读 !

于 2013-05-06T20:52:54.403 回答
0

考虑一个分层数据结构,其中每个节点可以是叶子,表示为标量对象,也可以是表示为数组的子树。如果您正在编写一个处理所有叶子的函数,它可以使用递归算法检查每个节点的类型;如果它是一个数组,它会遍历它并递归,否则它会处理该节点。

于 2013-05-06T20:47:12.130 回答