python3.8.3好用吗_Python3.8的几大新功能,你都知道吗?

10376869bff78a5b8d06b0543ad98d0f.png

1.字典逆序

我们都知道Python中的字典是无序的,Python3.6对这一问题进行了修订,默认情况下会按照键的创建顺序进行排序,但也仅限于此,你无法像列表那样对字典直接进行排序操作。

这一情况在Python3.8中进一步得到改善,Python3.8中reversed方法增加了对字典对象的支持,可以对字典进行逆序操作。

在下面这段代码中,对字典进行简单的迭代,将会按照顺序输出字典的键。

15e1989387e59d6180add4b16c24aaf9.png

现在改变一下代码,加入reversed方法:

9d064d886b8d751a4c803c1b7ed741b8.png

先来看使用Python3.6的运行结果(下图),可以看到在Python3.6中,字典是不支持recersed方法的。

3fd0aedcd85922f94fe09eeb1d84cda9.png

然后用Python3.8运行结果如下可以看到,字典按照键创建顺序的逆序进行了输出。虽然只是非常小的一点功能提升,但是在某些场景下对于字典对象的应用可能会起到非常关键的作用。

8ffcd67e29c7cdfdaa247c137e02bc39.png

2.位置参数

在Python3.8中的参数传递方面引入了一个新的特性:PEP 570 Positional-Only Argument——限定位置参数,下面就详细聊聊这究竟是怎么回事。

一般来说,Python中的参数传递有三种形式:位置参数、关键字参数和可变参数,为了避免不必要的麻烦,规定在可变参数之后只允许使用关键字参数。可是即便如此还是给程序员们留下了很大的自由空间,比如在可变参数之前,位置参数和关键字参数的使用几乎不受限制。这样就出现了一个问题,假如一个团队中很多人进行合作开发,函数的定义形式和调用模式是很难规范和统一的。

因此Python3.8就引入了一个“Positional-Only Argument”的概念和分隔符“/”,在分隔符“/”左侧的参数,只允许使用位置参数的形式进行传递。

举个例子来进行说明,首先建立下面这样一个函数,由于函数中使用了分隔符“/”,因此只能使用Python3.8运行。

defadd_num(x, y, z=100, /, a=100):

print(x + y + z + a)

尝试以下面这种方式调用函数:

add_num(1, 2, z=4, a=5)

结果在运行的时候发生了报错:

c13bfe3e04e600bb2ade3fc3193ae5f4.png

接着尝试全部以位置参数的形式调用函数(如下),结果顺利执行。可见“Positional-Only Argument”对分隔符“/”右侧的参数形式并没有限制。

#输入

add_num(1, 2, 4, 5)

#输出

12

那么如果只给定前两个参数,后面两个参数使用默认值又如何呢?通过下面的调用可以发现,也是可以正常运行的。

#输入

add_num(1, 2)

#输出

203

通过上面这个例子我们发现Python3.8对于参数传递的限制仅仅作用于分隔符“/”的左侧,而且只是在函数调用时发生作用。

3.赋值表达式

Python3.8中新增了赋值表达式“:=”操作符,简单来说就是把运算操作和赋值操作放在了一起,有点类似于“a+=b”这种表达方式,我想赋值表达式的出现应该是python追求简洁的传统理念所致。

来看下面这段代码,在func函数的if语句中,运算、赋值、判断操作在同一条语句中完成,即使变量a原本不存在也没关系。

# 输入

deffunc(x, y, z):

if(a := x + y) != z:

print(a)

else:

print(z)

func(1, 2, 5)

# 输出

3

当然,就上面这段代码本身来看,将 x+y 的结果进行赋值似乎意义不大,但是如果运算表达式的计算量非常大或者要进行大规模独写等操作的话,重复执行对代码的效率将造成大的影响;而如果事先对运算表达式赋值则需要多写一行代码。

目前来看,赋值表达式最重要的作用就是使代码变得更加简洁,至于运行效率的差异,目前还没有验证。

4.快速调试

在之前的Python版本中,“f表达式”——f'{expr}'的作用与eval函数基本相同,例如:

f'{[1, 2, 3, 4, 5, 6]}'的结果是列表[1, 2, 3, 4, 5, 6];

f'{3 + 2}'的结果是运算后的值5。

Python3.8中对该功能进行了优化,f'{expr}'语句中增加了对等号“=”的支持,在保留原来功能的基础上,还能够同时输出运算表达式本身。

例如执行先面这段代码,除了计算并输出运算结果外,还会将“=”和其左侧的算式一并输出:

x = 3

print(f'{x * 2= }')

执行结果:

b58c56effa248d3ca11b6d958a494dd3.png

f'{expr}'不仅适用于基本的算术运算,还能够进行其他对象的操作,以列表为例,令lst=[1, 2, 3, 4, 5, 6],现在对其进行扩展操作:

lst = eval('[1, 2, 3, 4, 5, 6]')

print(f'{lst = }')

print(f'{lst + [7] = }')

运行结果如下:

038bee45c3b8f470cabc53f75475de79.png

函数运算同样适用,例如对两个列表求交集,执行下面这段代码:

lst1 = [1, 2, 3, 4, 5]

lst2 = [3, 5, 7]

print(f'{list(set(lst1).intersection(set(lst2))) = }')

运行结果:

71b786f73ba1ae5d36358c8f2da117da.png

相比仅输出结果,连带运算表达式一起输出有助于定位检查,在调试代码的时候使用真的是快捷又方便。

5.共享内存

进程是系统进行资源分配的独立单位,在以前的python版本中,进程间的数据交互只能通过Queue、Pipes等方式来实现,数据无法直接共享。

在Python 3.8中,multiprocessing模块提供了SharedMemory类,可以在不同的Python进程之间创建共享的内存block。目前支持int、float、str、bytes、bool、None、numpy.ndarray等一部分Python对象。

还是举个例子来进行说明,在下面这段代码中建立了2个进程,在进程1中对列表中的每个元素执行+10操作,进程1结束后执行进程2,输出列表内容。

a1978322065383ae7d31505bf9c7ebab.png

由于进程之间数据无法共享,因此进程2中输出的列表是没有进行过+10操作的内容:

0b5d6983c9333e394f0303d0b1419f16.png

现在我们对代码进行一下小小的修改,nums不是作为一个普通的list,而是作为一个共享内存对象来创建,代码如下:

9d6861df12d485b886953fa69fc0ed42.png

由于shared_memory是Python3.8中的新增内容,因此在Python3.6下运行会出错,我们还是用Python3.8来运行这段代码(结果如下)可以看到,进程2中输出的结果与进程1中是一样的,两个进程之间通过shared_memory实现了数据共享。

3423913c5806625f16fd966ce687c761.png

当然,shared_memory在实际应用中肯定不会如此简单,

比如SharedMemory.ShareableList和SharedMemory.SharedMemory的使用本身有很多规则和限制、

比如需要考虑数据锁的问题等等,

但是共享内存确实为进程间通讯提供了一个新的解决方案,而且据说其通讯效率也是非常之高的。

Python3.8发布的新特性和新功能还有很多,对一些内置模块的改进和优化则更多,想尝鲜的同学可以点击阅读原文,了解Python3.8详情!你对Python3.8新特性怎么看,欢迎吱一声留言!

—————END—————

喜欢本文的朋友们,欢迎长按下图关注订阅号程序员小灰,收看更多精彩内容

程序员内推圈,优秀的内推机会等着你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值