关于Java和Python的一些思考

前言

最近实习在做的一些项目都是用Python来写的,虽然在之前就有学习过Python的语法,但真正用到的机会很少,而这次通过项目刚好让我对Python有了更进一步的认识,并且在此总结一下Python与之前用的比较多的Java的一些区别。

动态类型

Python与Java很大的一个区别在于Java必须在第一次声明变量时指定其类型,也就是所谓的静态类型,而Python则不一样,Python可以动态改变变量的类型。虽然Python的这个特性显得十分灵活,并且某些场景下可能开发效率更高一些,但稍不注意的话就有可能出错,在写代码时要更加注意。

缩进

Python不像很多语言使用花括号定义函数或类,而是使用的缩进将代码分割成块,使得代码可读性更高一些。

GIL

因为在项目中有许多要异步执行的任务,如果不了解Python的话,可能就会想到用多线程来解决问题,但实际上,Python中并不存在真正意义上的多线程,原因就是GIL的存在。GIL即全局解释器锁,Python的每个线程运行时首先要获得该锁,这也就意味着任何时刻仅有一个线程在执行,无法利用到多核的优势,使得多线程的效率甚至还不如单线程。但这也并非绝对的,在I/O操作或别的一些情况下,线程会主动释放GIL,这样别的线程就可以继续工作了,而如果是想完成一些CPU密集的任务的话,就只能通过进程或协程来解决了。

垃圾收集

不像Java使用的可达性分析算法,Python中的垃圾收集是使用的引用计数法,这也就意味着会有循环引用的问题。比如说,在以下这个代码中:

1
2
3
4
5
6
7
8
def f2():
while True:
c1=ClassA()
c2=ClassA()
c1.t=c2
c2.t=c1
del c1
del c2

在执行完上面的代码后,两个对象的引用计数都为1而非0,虽然它们都应该要被回收销毁的,但由于存在循环引用,所以不会被回收掉,也就导致了内存泄露。要解决这个问题,可以使用gc模块。