跳转至

下一个编程语言的选择

阅读前说明

首先我需要声明,作为一个业余python开发者,我对python还是比较喜欢的,丰富的第三方库+解释性语言特性,这对于做一些简单易用的脚本、工具等场景非常方便易用1,但如果要做一些相对复杂的项目,python的某些特性可能给我的开发带来一些麻烦

动态特性导致的问题

动态语言相对于静态语言来说,没有那么复杂的定义、声明等,编写起来是相当简洁易用的,在实现相同功能的场景下,用python可能几行到几十行就可以解决问题,用静态语言可能一两百行才能解决问题,更不要提需要配置一些环境变量等。但是,如果做一些项目时,动态特性对我来说反而是一个麻烦。由于它的动态特性,我只有处在运行时才能知道结果到底是什么,也因此只有在运行的时候才能发现一些bug,而这些bug不少都是因为类型导致的2,虽然不能保证写的每一行代码都不会出现问题,但有些问题我希望在做静态分析的时候就要解决掉,而不是等到运行的时候提示一大堆错误,这很影响开发效率。虽然我在这里介绍了类型注解,但python本身运行的时候会将这些类型注解当作注释一样,即使写了相当严谨的类型注解,但配合IDE依然避免不了下面这种错误:

关于此段代码的说明

这里只是作为一个示例,你可能很轻易的发现问题,而且遗漏的地方也没有影响实际结果,但如果分支比较多,就很容易漏写某个分支从而引发一些意外的bug

Python
def run_code(number:int)->bool:
    """
    @TODO 这里编写相应的逻辑代码
    """
    if number % 2 == 0:
        return True
if run_code(4):
    print('偶数')
else:
    print('素数')

动态特性导致的另一个问题是可能无法在debug状态获取有效的数据。我不清楚做cli的具体情况,但这几次在做GUI程序的时候,虽然处在debug状态,也能获取到某些变量运行时的数据,但是不少时候只能获取内存地址,没有办法准确的获取这个引用对象中的具体数据,导致只能一遍遍的测试+日志才能得到结果,这也会对开发效率带来一些影响

解释型特性导致的问题

我在这个博客中不止一次的吐槽过python打包的一些问题,虽然pyinstaller的方案相对比较成熟,但总会遇到一些奇奇怪怪的兼容性问题,比如工作目录的问题,某些代码的兼容问题等等,这就导致未被打包前可能一点问题都没有,但是打包之后会出现很多奇怪的问题,导致反反复复打包以处理这些额外引入的bug

至于其他方面的原因,比如作为开发桌面应用的我来说,类似外挂的pyqt/pyside方案在做GUI感觉不够协调、统一、易于调试,某些UI库的开源协议,打包体积大,不方便编译分发等,这些也会影响整体的开发效率和体验

下一步

就目前来看,C#似乎可以成为解决以上问题的最优解,静态、编译型语言的特性,有VS/Rider等优秀IDE,WPF开发支持热重载,(相对的)易于获取运行时数据,与Windows系统、UI库(winform/WPF)的集成度更高等特性是促使我选择的理由3

但请不要盲目冲动,在近期研究的过程中,也发现了C#.NET整个平台的一些问题,比如中文资料匮乏,配置环境麻烦且会出现一些奇奇怪怪的错误,(似乎)没有python那么丰富、易用、开源的第三方库4,相对高一些的上手门槛,特别多的语法特性,.NET Framework/.NET的割裂等问题,这些也是需要考虑的因素


  1. 如果你连写一段十几行的代码都要开IDE去编写,并且还要配置一些环境,那当我没说 

  2. 这个时候请不要急着说纯弱类型语言好等说法,这类语言在编写相对复杂的项目的时候可能问题更多,更不容易排查bug到底在哪儿 

  3. 可能你会好奇我为什么没有提到性能问题,这是因为就目前来说,PyQt的方案并没有明显的性能短板,再加上现阶段拖后腿的主要在文件I/O上,python的性能已经足够做一些不是很复杂的项目,所以更高执行性能的C#体现不出明显优势 

  4. 举几个例子:

    1. .NET Framework似乎没有内置JSON/ini解析库,还需要第三方库去支持;但python是内置这些库

    2. python有类似py7zr实现7z压缩/解压算法的库,实现原生操作7z压缩包;C#只有包装了7z.dll的库,但目前测试不成功,原因不明

    3. WPF/winform的很多知名UI库要收费,比如DevExpress等,当然也有一些是开源免费的;PyQt/PySide已有的知名UI库是开源的,且还有kivy/flet等开源UI库