众所周知,当我们使用Python等动态语言时,我们不必担心类型。因为动态类型让我们可以在没有这种关注的情即便如此,我们也可以使用函数type()
(在Python中)知道变量的类型。所以我的问题是:用动态语言进行类型检查有什么好处?
答案 0 :(得分:8)
在某些情况下,您希望进行类型检查。比如说,你想使用迭代器,但不是字符串 - 这是一个非常常见的情况。进行检查的最佳方法是键入检查项目是否为字符串:
if isinstance(someobj, str): # basestring in 2.x
...
我们使用isinstance()
,因为它允许子类以及类本身的实例。直接使用type()
进行检查几乎是一个非常糟糕的想法,但type()
确实有其他用途 - 有时您希望以类型检查以外的其他原因访问实例的类。
值得注意的是,Python允许使用子类钩子定义abstract base classes - 这允许isinstance()
进行一种鸭类型检查,其中检查类是否需要相关方法。例如,如果你想检查某个是一个序列,那么isinstance(obj, collections.Sequence)
不是坏的,因为它实际上不是传统意义上的类型检查,它会检查对象是否具有这些功能序列接口的必要条件(定义为in the docs)。
但是,一般情况下,应避免进行类型检查。在大多数情况下,可以简单地尝试并执行您想要的操作,然后在对象无法执行所需操作时捕获异常。 Python通常遵循请求宽恕而不是权限的规则,因此请尝试并优雅地处理错误,而不是事先进行检查。
简而言之:在动态语言中,我们依赖于鸭子打字。如果一个物体可以嘎嘎叫,我们可以认为它是一只鸭子。 99%的时间,可以嘎嘎叫的对象可以被视为鸭子,所以我们没事。然而,在极少数情况下,另一种可以嘎嘎叫的动物不应该被视为鸭子。我们可以区分它们的唯一方法是键入check,这没关系。不应该使用类型检查来检查我们的动物是否可以嘎嘎叫,但是,正如我们可以试着看到的那样(或者,如果我们现在不能使它嘎嘎叫,但仍然需要根据它进行操作,请直接检查嘎嘎的能力,而不是检查我们知道可以嘎嘎叫的类型。
答案 1 :(得分:1)
在python中,一切都是“OBJECT”,并且继承了一些“属性”和“方法”,使其具有唯一性。
因此,type是对象的“方法”和“属性”的“分类”。换句话说,类型检查为我们提供了该对象的实用性 “方法”和“属性”。
python“list”是一个序列,python“string”是一个序列,但它们具有不同的属性(一个是可变的,另一个是不可变的),因为它们具有独特的方法来处理它们的结构。例如,列表可以使用“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'
感谢阅读!
答案 2 :(得分:0)
考虑一个分层数据结构,其中每个节点可以是叶子,表示为标量对象,也可以是表示为数组的子树。如果您正在编写一个函数来处理所有叶子,它可以使用递归算法来检查每个节点的类型;如果它是一个数组,它会迭代它并递归,否则它会处理节点。