Python的类型系统

电子说

1.2w人已加入

描述

编者按:Feedly联合创始人、大数据与机器学习主管Kireet Reddy分享了对Python类型提示的看法。

升级到Python 3.6后,突然发现Python通过typing模块加入了类型提示。我得承认,我并不非常熟悉python社区,但是我觉得这样一种语言特性应该会引起不小的反响。

不管怎么说,我对这个新特性非常满意。在我职业生涯的大部分时间里,我在Java这个静态类型的世界中工作,python的类型提示多少提供了一些我很怀念的必需结构。

Python的类型系统

Python是一个动态类型语言,所谓的“鸭子类型”。使用Python编程时,动态类型大概是一把至为锋利的双刃剑。

基本上这意味着,Python并不会在编译步骤预先检查所有使用的类型是合法的,Python程序将继续愉快地运行下去,直到运行不下去为止,这时它会抛出一个TypeError。例如,下面这段Java代码编译不过:

publicstaticint add(int a, int b) { return a+b;}

...

add(1, "1");

Java编译器会立即抱怨传入了一个不兼容的类型。然而,你最喜欢的python IDE一点也不会抱怨这段等价的Python代码:

def add(a,b):

return a+b

...

add(1,"1")

你需要运行代码,才能碰到报错(整型和字符串无法相加)。

这真是糟糕。但是看看这个:

>>> add(‘hello’, ‘world’)

‘helloworld’

>>> add([1,2,3], [4,5,6])

[1, 2, 3, 4, 5, 6]

好吧,看来动态类型也不完全是坏事。这同样适用于类,只要对象存在恰当的方法,python代码可以直接工作,无需使用接口:

classDog(object):

def talk(self, quietly):

return'woof'if quietly else'BARK'

classCat(object):

def talk(self, quietly):

return'purr'if quietly else'YOWL'

def speak(a, quietly):

print(a.talk(quietly))

>>> speak(Dog())

woof

>>> speak(Cat())

meow

妙!少打很多字,代码非常凝练。

问题

在python项目的起初几周这让人感觉良好。不过接下来一周你可能离开这个项目去改进以前写的另一些代码。或者你需要和一个同事一起编程。

过了一段时间你回头看代码的时候,或者同事看你的代码的时候,看到speak(x)这行会觉得x太含糊。于是决定跳转到speak的定义,结果看到了a.talk。下面就没法进一步跳转到定义追踪下去了,需要手动搜索查看哪些地方实现了talk这一方法,接着还需要查看这些方法做了什么,尝试推断出speak在talk上施加的一般契约。

解决方案

类型提示让你可以提供更多的上下文。重写上面的代码:

classDog(Animal):

def talk(self, quietly: bool) -> str:

return'woof'if quietly else'BARK'

classCat(Animal):

def talk(self, quietly: bool) -> str:

return'purr'if quietly else'YOWL'

def speak(a:Union[Dog, Cat], quietly: bool) -> None:

print(a.talk(quietly))

你可能已经注意到了,类型提示位于冒号和箭头之后。注意它传递的额外信息。现在我们一眼就能看到speak期望Dog或Cat,而布尔值标记指明是否应该小声说话(返回小写字母)。如果我们期望将来有更多说话者的类型,那么这种写法会变得累赘吗?会,但这大概意味着我们应该引入基类。

没有类型提示,基本上很难编写不言自明(self-documenting)的代码。你将不得不重度依赖极好的命名,一丝不苟的注释,还有代码的清洁程度。这其实是相当高的门槛。

一个额外的好处是,PyCharm等许多IDE支持类型提示,如果你没有传入恰当的参数,会通过下划曲线标出错误。

我强烈建议在新代码中使用类型提示,接着逐渐更新老代码。它们不仅为你节省了一些阅读代码的时间,更重要的是减轻了记住你所有的变量应该是什么类型的心智负担。

如果你想了解更多关于类型提示的内容,请查看python文档。升级到Python 3.6后我们在Feedly强调了类型提示的重要性,后来我收到了这么一条slack消息:

(译文:加入feedly前我并不知道python有类型提示。有了类型提示,阅读其他人的代码要容易太多!)

一切如你所想地工作的时候,感觉真不错。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分