美文网首页python程序员Python
为什么我要把python版本升级到3.8?是因为它的稳定?

为什么我要把python版本升级到3.8?是因为它的稳定?

作者: CXYsummer | 来源:发表于2020-08-06 16:27 被阅读0次

    你是否还在使用Python3.7,3.6……甚至是更老的Python版本?

    确实,尝试去使用一个比较“新”的Python版本存在一定风险,我们容易遇到一些问题:

    • 生态,各种库的支持,兼容性……

    • 不同版本的解释器存在差异,以前的项目还能不能继续使用是个问题……

    • 新的特性或者功能太香,我实在忍不住更新了却遭遇到bug……


      image.png

    实际上,Python3.7的正式版最早发布于2018年06月15日,截止目前,Python3.7的最高版本是3.7.4(于2019年7月8日发布,距离现在的2020年7月已经有超过一年的时间!也就是已经停止更新一年了),所以我们基本可以说,它其实也并不算“新“了。

    而Python3.8的首个正式版发布于2019年10月14日,目前已经持续维护将近一年,更新到了3.8.5版本(于2020年7月20日更新)。

    根据Python官网,目前最新的Python版本为3.9,目前还处于测试中,预计将在今年的10月发布第一个正式版本:


    image.png

    在Python的官网上我们可以看到,Python3.7的Maintenance status(维护状态)为security,而Python3.8则是bugfix,在这里解释一下Python的几种维护状态:


    image.png
    也就是说,处于bugfix状态,并且已经持续更新了将近一年的Python3.8实际上已经比较成熟,可以尝试在生产环境当中使用了。

    当然,如果你对稳定性要求非常高,那么选择Python3.7或者其它维护状态为security的版本即可,因为除非遇到安全性的问题,它们几乎不会再进行更新了(比如Python3.7,至今已经一年没有进行更新),所以使用起来会更更更稳。

    但是!Python3.8太香了!

    一起来看看它的新变化,看完你肯定想用

    Python3.8:近乎全方位的性能提升

    数据来自Python官网

    测试结果的单位是纳秒(数字越小,性能越好),可见Python3.8的性能提升几乎是全方位的


    image.png
    image.png

    新的语法:海象运算符 :=

    除了性能上的提升外,最值得一提的变化是,Python3.8中加入了新的语法,海象运算符::=

    海象运算符是一个赋值表达式,它能够减少我们的一些重复性操作,使得代码编写更加流畅、简洁易读。

    • 一个简单的例子,首先这是在Python3.8以前的写法:
    # 我有一个盒子,里面装着三样水果,并且装不下更多了
    myBox = [ 'apple', 'banana', 'orange' ]
    
    # 现在往里面装入新的水果
    myBox.append('trump')
    
    # 但是实际上,它之前已经装满了,再往里装就要爆炸了!
    
    # 那么要进行判断,并且告诉我们,我们的盒子炸了:
    if len(myBox) > 3:
        print('盒子炸了,最多只能装3样水果,而你却装了{}样!'.format(len(myBox)))
    
    

    可以看到,我们在这个例子中使用了两次len(myBox)来获得盒子列表的长度,非常的麻烦。。。

    好的,我们优化一下,使用一个变量存储盒子列表的长度:

    # 我有一个盒子,里面装着三样水果,并且装不下更多了
    myBox = [ 'apple', 'banana', 'orange', 'trump' ]
    
    # 记录长度
    size = len(myBox)
    
    # 那么要进行判断,并且告诉我们,我们的盒子炸了:
    if size > 3:
        print('盒子炸了,最多只能装3样水果,而你却装了{}样!'.format(szie))
    

    很好!但是我又发现,我们虽然少写了一次len(myBox),少调用了一次len(),但却又多写了三次size!

    对于程序员而言,多写几个字很容易造成生理及精神上的疲劳,甚至造成心理上的创伤,导致抑郁,最后形成网抑云之类的严重症状。

    万一这不是一个只有几行代码的小例子,而是一个天大的项目呢?那一定会写断手!幸好,海象运算符的出现防止了这一点:

    # 现在可以这么写
    myBox = [ 'apple', 'banana', 'orange', 'trump' ]
    
    # 在这一步中,我们在判断myBox列表长度的同时又将其记录为了变量size
    if (size := len(myBox)) > 3:
        print('盒子炸了,最多只能装3样水果,而你却装了{}样!'.format(szie))
    

    是的!有了海象运算符,我们可以在判断过程中赋值新变量。

    对比一下效率的提升:原先的步骤是: 执行len(myBox) → 创建变量size → 访问size进行判断 → 访问size进行打印现在变成了:执行len(myBox)创建变量size的同时进行判断 → 访问size进行打印

    原本的四个步骤直接减少了两步。

    • 下面的例子是数据筛选,我们需要帮助用户过滤掉不存在的学号,并找到不及格的学生:
      一般写法:
    # 学生表
    # key为id(主键),value为学生对象(这里不写对象了,直接用dict方便表示)
    students = {
        1: {'name': '小明', 'score': '及格'},
        3: {'name': '小红', 'score': '不及格'},
        4: {'name': '小绿', 'score': '不及格'}
    }
    
    # 尝试找到学号1-4,并且成绩为不及格的学生
    # 学号2的那位实际上被开除了,但是用户并不知道
    results = []
    for stuId in range(1, 5):
        student = students.get(stuId) # 如果是不存在的key则会取到None
        if student and student['score'] == '不及格': # 需要过滤掉是None的值,并取不及格的学生
            results.append(student)
    
    # 返回结果给用户
    print(results)
    

    使用海象运算符和列表推导式可以轻松完成这项工作:

    print([student for stuId in range(1,5) 
      if (student := students.get(stuId)) and student['score'] == '不及格' ])
    
    • 以及,当你希望连续获得用户输入,直到某个关键字时终止并给出结果时:
    inputs = []
    
    # 让用户输入任意个需要进行求和的数
    while True:
        userInput = input('请输入数字或"求和":')
        # 当输入为”求和“时结束循环
        if userInput == '求和':
            break
        inputs.append(int(userInput))
    
    # 打印求和结果
    print('求和的结果是:', sum(inputs))
    

    使用海象操作符:

    inputs = []
    
    while (userInput := input('请输入数字或"求和":')) != '求和':
        inputs.append(int(userInput))
    
    print('求和的结果是:', sum(inputs))
    
    • 或者,帮助你处理一个函数的返回数据,这里是一个网络请求的例子:
    import requests
    
    # 爬取数据,或者从某个api获得数据时,要对请求状态码进行验证
    if (resp := requests.get('某地址')) and resp.status_code == 200:
        # 当请求成功(如状态码200)时进行处理
        pass
    
    print(resp)
    
    • 也可以这么写,会降低一些可读性。但是很爽。
    import requests
    if (resp := requests.get('某地址')).status_code != 200: pass
    
    print(resp)
    
    • 你也可以在传统的循环中使用,这里是循环10次打招呼:
    count = 0
    while (count := count + 1) <= 10:
        print('hello')
    
    # 看看count的变化
    print(count)
    

    这里就不再举更多例子了,海象运算符还有更多用法等你发现

    函数的新语法:形参限定符(仅限位置形参)

    由于官方文档的名字有点晦涩难懂,所以“形参限定符”实际上是我自己起的名字……但是它确实很好懂对不对。。!!

    • 仅限位置形参 以及 仅限关键字形参:/ 和 *
      它是一个新的函数形参语法,下面是仅限位置形参/的例子:
    # 一个函数
    def test(a, b, /, c):
        print(a, b, c)
    
    # 进行测试
    test('我是a', '我是b', '我是c') # 能够输出
    test('我是a', '我是b', c = '我是c') # 能够输出
    test('我是a', b = '我是b', c = '我是c') # 报错
    

    上面的例子说明,在函数test的形参列表里,位于限定符/前面的参数是仅限位置形参:只能用固定位置对应的方式传参,而不能使用如: b = '我是b' 这样的键值对应的方式传参(叫做关键字形参)。

    位于限定符/后面的参数既可以使用固定位置形参,也可以使用关键字形参。

    对刚才的例子稍作修改,下面是仅限关键字形参限定符*:

    # 对刚才的例子稍作修改
    def test(a, b, /, c, *, d, e):
        print(a, b, c, d, e)
    
    test('我是a', '我是b', c = '我是c', d = '我是d', e = '我是e') # 能够输出
    test('我是a', '我是b', c = '我是c', d = '我是d',  '我是e') # 报错
    

    也就是说,位于*后面的参数只能以关键字形参的方式传入。

    并且,限定符与kwargs不冲突:

    def test(a, b, /, **kwargs):
        print(a, b, kwargs)
    
    test('我是a', '我是b', a = '我也是a', b = '我也是b', c = '我是c') # 能够输出
    
    # 输出结果如下:
    # 我是a 我是b {'a': '我也是a', 'b': '我也是b', 'c': '我是c'}
    

    如果函数需要接受许多不确定的参数,那这确实是一个不错的特性

    Python3.8对f-string的补充:说明符 =

    什么是说明符呢,下面举这么一个字符串例子:

    # 定义变量
    data = ['哈哈', '嘻嘻']
    count = len(data)
    
    # 打印
    print(f'{data=}, {count=}')
    
    • 打印结果是:data=['哈哈', '嘻嘻'], count=2
      可以看出,在说明符=左侧的表达式运算结果或者变量将被输出到说明符的右侧,也就是用:变量名称或表达式结果 = 变量的值或表达式结果 的这种格式进行打印输出。

    比如一个表达式的例子:

    a = 1
    b = 2
    
    # 打印
    print(f'{a+b=}')
    
    • 打印结果是:a+b=3
      是不是很有趣。。。

    并且,它可以帮你规范打印格式:

    a = 1023
    b = 1
    
    # 打印
    print(f'{a+b=:,d}')
    
    • 打印的结果是:a+b=1,024
      自动加上了千分位逗号。。。够意思了

    关于Python3.8更详细的变化可以在Python官网查看:

    • 详细的可以看官网文档:Python3.8有什么新变化?
    • 或者更详细的更新日志:Python3.8更新日志

    关于升级到Python3.8

    只能够下载新的安装包进行全新安装,无法平滑升级

    关于库的迁移

    建议重新安装所有的库,而不是将旧版本的库直接移动到新版本(虽然也可以这么做!)

    可以使用pip freeze > req.txt 将当前python解释器所安装的库全部导出到txt

    升级完python后使用 pip install -r req.txt 一键安装

    关于Spyder

    spyder是一个我爱用的 Python IDE,它由python + pyqt编写。

    断点、交互式编码、变量管理器、代码分析、ipython、cython控制台……查看dataframe、在控制台显示图片它都能做到,以及有更多的功能等你解锁……

    调代码,做测试,搞分析,非常好用!选中一片代码,按下F9即可运行选中的代码片段……并且它是开源的,已有5000+star:https://github.com/spyder-ide/spyder

    image.png

    现在,它能够很好的支持Python3.8了,而安装也十分容易:

    pip install spyder
    

    安装后使用命令行启动

    spyder3
    

    我不得不吐槽的是,实际上我们安装的是最新的spyder4,但是启动名称还是叫spyder3?这是不是有点钦定的感觉。。

    • 值得注意的是,使用pip安装的spyder不会自动创建桌面快捷方式,需要我们手动进行创建:


      image.png

      使用pip安装spyder后,spyder3.exe位于你Python路径下的Scripts目录中,将其发送到桌面快捷方式,并设置图标即可。

    图标的位置如下(Python38是你安装Python的路径):D:\Python38\Lib\site-packages\spyder\windows\spyder.ico

    我最终还是没能抗下诱惑,准备升级到Python3.8……

    我已经升级了,确实很好用,产品经理很爱我

    热文推荐:

    全网首发‖最全最新小白一天即可入门的python教程

    相关文章

      网友评论

        本文标题:为什么我要把python版本升级到3.8?是因为它的稳定?

        本文链接:https://www.haomeiwen.com/subject/xnzzrktx.html