动态类型一时爽,代码重构火葬场?

浏览: 1701

作者:刘志军,6年+Python使用经验, 高级开发工程师,目前在互联网医疗行业从事Web系统构架工作

个人公众号:Python之禅(微信ID:vttalk)


题图:Photo by Timo Wagner on Unsplash

江湖有言:“动态类型一时爽,代码重构火葬场”,听起来有点耸人听闻,但也没有想象中的那么严重,因为 Python 在大型项目的应用实在太多。Python作为动态语言,代码简洁、灵活,抛开运行效率不说,但存在的一些问题也是事实,例如:

1、IDE的智能提示比较鸡肋,举个例子,字符串有个 startswith 方法,你很容易忽略中间那个“s”,如果么有 IDE 的帮助,不得不去查个文档。(其实现在的PyCharm 已经非常智能了,即使没有类型声明。)

2、大部分错误只有在程序运行的时候才能被发现,编译过程中只能发现简单的语法错误。

3、接口调用全靠文档注释说明,虽然我们可以使用 docstring,但是代码更新之后,你的 docstring 可能就没有同步更新。

这些问题在大型项目,特别是多人合作的项目上显得更为突出。所以遵循代码规范、Code Review 就变得尤为重要,如果能从语法层面上去规范代码无疑是最省成本的,所以在 Python3.5,也就是 PEP484 中就有了类型提示(Type Hints)。定义函数时,可以你指定函数的返回值类型、参数的类型。

以前定义一个函数可以接收任何类型的数据:

def greeting(name):
   return "Hello" + name

greeting("bob")
greeting(1)

程序运行前,不会有任何错误提示,虽然我们知道字符串和数字是不支持“+”操作的。

在 Python3.5 中,用 Type Hint  写法是这样的:

def greeting(name: str) -> str:
   return 'Hello ' + name

上面就是静态类型的写法,多了 「: str」与 「-> str」,前者用来说明 name 的类型,后者指函数返回值的类型,我们在写代码的过程中IDE也能提示我们写得不对:

除了 IDE 之外,我们还有更强大的静态类型检查工具,叫 mypy,这个工具也是由 Python 之父 Guido 亲自操刀实现的静态类型检查工具。

# 先安装mypy
pip install mypy

$ mypy test.py
test.py:4: error: Argument 1 to "greeting"
has incompatible type "int"; expected "str"

有了类型提示,Python在代码调用、重构、甚至是静态分析等方面有了更好的效果,不但减轻了开发时自行进行型态检查的负担,更重要的是,由于有了型态上的提示,让过去 Python 整合开发工具上做不好的各种智能提示、重构等功能有了统一的参考标准。

某种意义上类型提示只是一种辅助功能,虽然我们加了数据类型提示,但是对于 Python 解释器来说,它会直接忽略掉类型提示信息,哪怕类型有误也不会阻止程序的运行。

而对于变量的类型声明,在 PEP484 中可以通过类型注释来说明,就是以注释的方式来说明变量的类型,例如:

from typing import List

x = []                # type: List[Employee]
y = [1, 2]            # type: List[int]
y.append("a")

在 Python3.6,也就是 PEP526 的提案中,针对变量注解做了进一步优化,将类型的声明作为了语法的一部分,这样比起注释可读性更强,例如:

my_var: int  # 声明为整数类型的变量
my_var = 5  # 通过类型检查
other_var: int = 'a'  # 给整数类型变量赋值字符串,检查器会报错,但是解释器运行是不会有任何问题
print(other_var)

运行mypy

mypy xx.py  # 运行类型检查器
xx.py:3: error: Incompatible types in assignment (expression has type "str", variable has type "int")

python test.py # 运行解释器

拥有了强大的类型提示之后,你还敢说重构代码是火葬场吗?不过我反倒觉得动态语言变得越来越臃肿起来,例如:

T = TypeVar('T')
S = TypeVar('S')
class Foo(Generic[T]):
   def method(self, x: T, y: S) -> S:
   # Body

这让一门原本简洁优雅的语言跟Java一样臃肿了,好在类型提示在Python中只是一种可选操作,而且对解释器来说完全是不可见的。而且这种写法也不是Python 的主流做法,大家可以去看看主流框架的源码,很少用这种特性。

虽然 Java 是一门很成功的语言(而且也开始加入动态类型等特性),但我更喜欢 Python 的理由是它给了开发者最大的自由。至于说代码好不好维护,真的跟人有关,毕竟大家都是成年人!( We are all consenting adults)

本文可接受反驳

Python的爱好者社区历史文章大合集

2018年Python爱好者社区历史文章合集(作者篇)

福利:文末扫码关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复“ 课程 ”即可获取:

小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

小编的Python的入门免费视频课程

小编的Python的快速上手matplotlib可视化库!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告扩展制作免费学习视频。

玩转大数据分析!Spark2.X + Python精华实战课程免费学习视频。

推荐 0
本文由 Python爱好者社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册