是时候将你的Python版本升级到3.8了!为什么我选择Python3.8?
你是否还在使用Python3.7,3.6……甚至是更老的Python版本?
确实,尝试去使用一个比较“新”的Python版本存在一定风险,我们容易遇到一些问题:
- 生态,各种库的支持,兼容性……
- 不同版本的解释器存在差异,以前的项目还能不能继续使用是个问题……
- 新的特性或者功能太香,我实在忍不住更新了却遭遇到bug……
实际上,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月发布第一个正式版本:
分支版本 | 发布计划 | 维护状态 | 首个正式版本 | 终止更新 | 发布 |
---|---|---|---|---|---|
3.9 | PEP 596 | bugfix | 2020-10-05(时间未到) | 待定 | Łukasz Langa |
3.8 | PEP 569 | bugfix | 2019-10-14 | 2024-10 | Łukasz Langa |
3.7 | PEP 537 | security | 2018-06-27 | 2023-06-27 | Ned Deily |
3.6 | PEP 494 | security | 2016-12-23 | 2021-12-23 | Ned Deily |
3.5 | PEP 478 | security | 2015-09-13 | 2020-09-13 | Larry Hastings |
在Python的官网上我们可以看到,Python3.7的Maintenance status(维护状态)为security,而Python3.8则是bugfix,在这里解释一下Python的几种维护状态:
维护状态 | 说明 |
---|---|
features | 功能预览版本(最不稳定),期间允许加入新功能、错误修复以及安全性修补 |
prerelease | 预发行版本(较不稳定),期间允许进行对功能存在的问题进行修复、错误修复以及安全性修补 |
bugfix | 正在维护的版本(稳定版),期间允许进行错误修复以及安全性修补,将会及时发布新的二进制文件 |
security | 最稳定,到这里版本几乎已经固定了,期间只允许进行安全性修补,但是不会再发布新的二进制文件,最多可能更新源代码 |
end-of-life | 终止维护,不在进行有关的发布 |
也就是说,处于bugfix状态,并且已经持续更新了将近一年的Python3.8实际上已经比较成熟,可以尝试在生产环境当中使用了。
当然,如果你对稳定性要求非常高,那么选择Python3.7或者其它维护状态为security的版本即可,因为除非遇到安全性的问题,它们几乎不会再进行更新了(比如Python3.7,至今已经一年没有进行更新),所以使用起来会更更更稳。
但是!Python3.8太香了!
一起来看看它的新变化,看完你肯定想用
Python3.8:近乎全方位的性能提升
数据来自Python官网
测试结果的单位是纳秒(数字越小,性能越好),可见Python3.8的性能提升几乎是全方位的
性能测试项 | Python 3.3 | Python 3.4 | Python 3.5 | Python 3.6 | Python 3.7 | Python 3.8 |
---|---|---|---|---|---|---|
变量和属性读取性能 | - | - | - | - | - | - |
read_local | 4.0 | 7.1 | 7.1 | 5.4 | 5.1 | 3.9 |
read_nonlocal | 5.3 | 7.1 | 8.1 | 5.8 | 5.4 | 4.4 |
read_global | 13.3 | 15.5 | 19.0 | 14.3 | 13.6 | 7.6 |
read_builtin | 20.0 | 21.1 | 21.6 | 18.5 | 19.0 | 7.5 |
read_classvar_from_class | 20.5 | 25.6 | 26.5 | 20.7 | 19.5 | 18.4 |
read_classvar_from_instance | 18.5 | 22.8 | 23.5 | 18.8 | 17.1 | 16.4 |
read_instancevar | 26.8 | 32.4 | 33.1 | 28.0 | 26.3 | 25.4 |
read_instancevar_slots | 23.7 | 27.8 | 31.3 | 20.8 | 20.8 | 20.2 |
read_namedtuple | 68.5 | 73.8 | 57.5 | 45.0 | 46.8 | 18.4 |
read_boundmethod | 29.8 | 37.6 | 37.9 | 29.6 | 26.9 | 27.7 |
变量和属性写入性能 | - | - | - | - | - | - |
write_local | 4.6 | 8.7 | 9.3 | 5.5 | 5.3 | 4.3 |
write_nonlocal | 7.3 | 10.5 | 11.1 | 5.6 | 5.5 | 4.7 |
write_global | 15.9 | 19.7 | 21.2 | 18.0 | 18.0 | 15.8 |
write_classvar | 81.9 | 92.9 | 96.0 | 104.6 | 102.1 | 39.2 |
write_instancevar | 36.4 | 44.6 | 45.8 | 40.0 | 38.9 | 35.5 |
write_instancevar_slots | 28.7 | 35.6 | 36.1 | 27.3 | 26.6 | 25.7 |
数据结构读取性能 | - | - | - | - | - | - |
read_list | 19.2 | 24.2 | 24.5 | 20.8 | 20.8 | 19.0 |
read_deque | 19.9 | 24.7 | 25.5 | 20.2 | 20.6 | 19.8 |
read_dict | 19.7 | 24.3 | 25.7 | 22.3 | 23.0 | 21.0 |
read_strdict | 17.9 | 22.6 | 24.3 | 19.5 | 21.2 | 18.9 |
数据结构写入性能 | - | - | - | - | - | - |
write_list | 21.2 | 27.1 | 28.5 | 22.5 | 21.6 | 20.0 |
write_deque | 23.8 | 28.7 | 30.1 | 22.7 | 21.8 | 23.5 |
write_dict | 25.9 | 31.4 | 33.3 | 29.3 | 29.2 | 24.7 |
write_strdict | 22.9 | 28.4 | 29.9 | 27.5 | 25.2 | 23.1 |
堆栈、队列操作性能 | - | - | - | - | - | - |
list_append_pop | 144.2 | 93.4 | 112.7 | 75.4 | 74.2 | 50.8 |
deque_append_pop | 30.4 | 43.5 | 57.0 | 49.4 | 49.2 | 42.5 |
deque_append_popleft | 30.8 | 43.7 | 57.3 | 49.7 | 49.7 | 42.8 |
Timing loop | - | - | - | - | - | - |
loop_overhead | 0.3 | 0.5 | 0.6 | 0.4 | 0.3 | 0.3 |
新的语法:海象运算符 :=
除了性能上的提升外,最值得一提的变化是,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则会取到Noneif 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 == '求和':breakinputs.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)时进行处理passprint(resp)
- 也可以这么写,会降低一些可读性。但是很爽。
import requests
if (resp := requests.get('某地址')).status_code != 200: passprint(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
只能够下载新的安装包进行全新安装,无法平滑升级
- Python下载地址:https://www.python.org/downloads/
安装新版本后将旧的环境变量改到新的Python路径即可完成升级!
关于库的迁移
建议重新安装所有的库,而不是将旧版本的库直接移动到新版本(虽然也可以这么做!)
可以使用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
现在,它能够很好的支持Python3.8了,而安装也十分容易:
pip install spyder
安装后使用命令行启动
spyder3
我不得不吐槽的是,实际上我们安装的是最新的spyder4,但是启动名称还是叫spyder3?这是不是有点钦定的感觉。。
- 值得注意的是,使用pip安装的spyder不会自动创建桌面快捷方式,需要我们手动进行创建:
使用pip安装spyder后,spyder3.exe
位于你Python路径下的Scripts
目录中,将其发送到桌面快捷方式,并设置图标即可。
图标的位置如下(Python38是你安装Python的路径):
D:\Python38\Lib\site-packages\spyder\windows\spyder.ico
我最终还是没能抗下诱惑,准备升级到Python3.8……
我已经升级了,确实很好用,产品经理很爱我
是时候将你的Python版本升级到3.8了!为什么我选择Python3.8?相关推荐
- python版本升级及pip部署方法
Python版本升级 CentOS 6.3自带的Python版本为2.6,首先需要升级到2.7版本.由于旧版本的Python已被深度依赖,所以不能卸载原有的Python,只能全新安装. 1.下载Pyt ...
- Python语言学习:解决python版本升级问题集合(python2系列→Python3系列)导致错误的总结集合
Python语言学习:解决python版本升级问题集合(python2系列→Python3系列)导致错误的总结集合 目录 Python版本升级的原因 Text and binary data in P ...
- python版本升级
python版本升级 背景 在对centos机器升级Python版本从3.6到3.10后,pip安装出现了一些问题 [解决pip is configured with locations that r ...
- linux中如何升级python版本号,linux的python版本升级
可利用Linux自带下载工具wget下载,如下所示: #tar -zxvf Python-2.7.13.tgz 进入解压缩后的文件 #cd Python-2.7.13 在编译前先在/usr/local ...
- python3.8还是3.7_选择 Python3.6 还是 Python 3.7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 选择 Python3.6 还是 Python 3.7 Python 3.7 已经发布了, 又有新版本玩喽!!但是有选择症的你,怎么办呢?像追剧一样,赶快升 ...
- python比较好的视频教程-哪里有免费的python3教程啊?最好是有例子的视频教学...
网上有很多的,你可以搜千锋Python视频教程看看. Python编程语言自1991年首次发布,至今已经走了很长一段路了.在众多编程语言中,Python得以占有一席之地已经很不错了,如今,它正快速成为 ...
- python安装步骤电脑版-超详细的小白python3.X安装教程|Python安装
安装Python 因为Python是跨平台的,它可以运行在Windows.Mac和各种Linux/Unix系统上.在Windows上写Python程序,放到Linux上也是能够运行的. 目前,Pyth ...
- php和python区别-PHP与Python语言有哪些区别之处?选择哪一个好?
其实针对不同阶段的学者来说,他们的需求自然也有所不同.本篇文章主要分析了php和python哪个好以及介绍PHP与Python的区别之处,希望对还在为学习PHP和Python中哪一个语言而摇摆不定的朋 ...
- python是一种动态语言、这意味着_【python编程的优点是什么?难怪选择python的人越来越多了】- 环球网校...
[摘要]Python是一种动态解释的.强类型定义语言:编写它时不需要定义变量类型.python判断值的类型的方法是什么,那么python编程的优点是什么?难怪选择python的人越来越多了,所以你知道 ...
最新文章
- 使用Arthas 获取Spring ApplicationContext还原问题现场
- Linux显示某文件中有关某字符串的信息
- 获取用户列表为空_Python中最常见的10个列表操作
- P3704-[SDOI2017]数字表格【莫比乌斯反演】
- 2021未来职业规划以及对过去的总结
- linux 进程的vss rss uss,内核/内存管理中的VSS/RSS/PSS/USS
- bzoj 2296: 【POJ Challenge】随机种子
- matplotlib之subplot和动态作图(笔记六)
- linux蚂蚁矿池教程,蚂蚁矿机Z9使用教程
- 我所知道坦克大战(单机版)之 让子弹飞、让坦克控制子弹开炮
- PHP微信网页授权登录
- 电脑x64和x86安装软件的区别讲解分享
- 怎么知道网站是否被黑 服务器是否被入侵呢
- BGA“焊点”虚焊原因分析及控制方法
- ajax localhsot,ajax请求nodejs后台,开启服务器后,localhost:3000/index.html页面既没有报错,也没有文字。。。...
- Windows 10打开蓝牙已关闭解决方法
- 动态创建多个echarts图表
- webpack对css文件打包:css-loader和style-loader版本过高问题
- [路由][教程]OpenWrt设置为交换机+无线功能教程
- 35岁,年入60万,我却从菊厂离职了!