Python3.8新特性

介绍

Python 3.8 发布于 2019 10 14 日,在很多方面都进行了提升,特别是加入了海象运算符,用习惯了还是挺方便的,大家快来尝鲜吧。

知识点

  • 海象运算符
  • 字典反转
  • f-string
  • 仅限位置形参

Python3.8安装

官方网址:

Python Release Python 3.8.1 | Python.org

根据自己系统选择所需下载版本,我是Windows x86系统选的是这个图形化的安装自动安装,绝大多数情况下,特别是学习阶段,32 位还是 64 位没有区别。今后我们编写的所有 Python 代码,也不会区分是多少位。

大家现在所用的 Python C 语言实现的 CPython,它可以直接使用 C 语言编写的模块。这些 C 语言模块针对不同位数的 Python 编译出来的结果只能用在特定的版本上。

大多数情况下,这些模块会同时提供针对不同位数的版本,直接使用 pip install 的时候会自动匹配。只是有些时候手动下载安装包的时候,需要注意版本要匹配一致。

开始安装

可以选择Install Now(立即安装),也可以选择Customize installation(自定义安装),想偷懒的可以直接选择Install Now

自定义安装有 2 个对话框选择,

第一个默认都是勾选上的,每个选项是啥意思介绍如下:

  1. Documentation 离线的 .chm 格式文档,必须保留。英文还 OK 的小伙伴可以直接看这份文档,比所有书都靠谱。看英文有压力的,平时随时查查标准库模块用法什么的是极好的。
  2. pip Python 包下载工具,必须保留。(想找虐的随意)
  3. tcl/tk and IDLE ,说来话长,保留就对了。
  4. Python test suite,这个可以没有,当然留下来也没关系。
  5. py launcher,前面介绍过了。这里额外注意的是 for all user 选项,可以选择是否对所有用户安装。如果对所有用户安装,则需要 administrator 的权限。

2 个对话框是高级选项:

  • Install for all user,是否对所有人安装,如果是,需要 administrator 的权限,并且安装路径会有所不同。
  • 关联文件到 Python,这个保持原样即可。它就是把 .py 文件和 python 程序关联起来,这样双击 .py 文件的时候,自动就用 python 去执行了。
  • 创建快捷方式,保持原样即可。
  • 添加 Python 到环境变量,第 2 次修改的机会
  • 预编译标准库,一次性的把标准库的 .py 都预编译成 .pyc,没什么必要,会多花费安装时间,不选
  • 两个 download debug xxx ,不知道哪里会用到,都不选

最下面是指定安装路径,个人意见,保持默认即可。如果取消勾选为所有人安装,则默认安装的路径会比较深,这个看上去有点不舒服,但是绝大多数情况下我们都不会直接造访该目录,所以不会有什么影响。

我个人的推荐操作是 不选择对所有用户安装,这样如果想使用多个用户,每个用户有自己选择的自由。“

安装后的基本测试

安装完成后,新打开一个命令行窗口,win + r,然后输入 cmdps:“ 注意,必须重新打开,在安装 Python 前已打开的命令行不会自动更新环境变量。”)

依次执行下面的命令:

# 注意,-0 后面是数字 0,不是字母 o

py -0

或者

py --list

这就是调用 Python 启动器,它显示出系统中已安装的 Python 版本。

python --version

这是直接调用 Python 解释器,打印出它的版本。

pip --version

为什么要测试这 3 个命令,因为它们分别安装在了不同的位置,都工作正常了,就证明安装没有问题了。

想要了解更多细节,我们来查看 PATH 环境变量。

安装后的 PATH 变化

因为没有选择为所有用户安装,所以环境变量看当前用户的:

安装时的选择不同,这里环境变量出现的位置也会有所不同”

上面 3 条就是安装后自动添加的。

注意,如果 launcher 没有取消勾选 for all user,则会默认安装在系统目录下,就不需要添加到 PATH,这里就只有 2 条新增。

安装目录详情

先来看 C:\Users\Davy\AppData\Local\Programs\Python\Python38,也就是 Python 的安装路径,它是包含 python.exe 的目录。

其它目录的作用:

  • DLLs,静态链接库,里面是一些 .dll  .pyd 文件,一般不会直接和这个目录打交道
  • Doc,文档,里面就是一个 python381.chm,快捷方式里包含了该文档路径,所以平常不会直接访问
  • include,头文件,基本上不会用到
  • Lib,这个目录最最重要,几乎所有的标准库源码都在这里面了,大部分平常都不会去动它们,除了其中一个子目录:
    • site-packages 后续安装的第三方模块和包都会出现在这里,所以偶尔出现问题,我们会造访这里。
  • libs,几乎不会直接用到,注意和 Lib 区分开。(因为 Windows 系统路径不区分大小写,所以 Lib 实际会展示成 lib
  • Scripts,后续安装的第三方包如果提供了命令,可执行文件就会出现在这里。例如 pip.exe 就是在此目录下,而 Lib 目录下保存的是 pip 的源码。
  • tcl,仍然是说来话长,略过
  • Tools,自带的一些 Python 脚本,包括一些 demo,其中有些可以作为学习参考。

最后看 launcher 的目录,它要管理所有的 Python 版本,所以它是超脱在外的,安装在了 Python38 的上级目录中。

启动菜单详情

安装 Python 后在开始菜单会多出来 4 个快捷方式,一般很少用,做一个简单的介绍:

  • IDLE (Python 3.8 64-bit),用来启动 IDLE ,以后再详细介绍它。
  • Python 3.8 Module Docs (64-bit),点击会自动启动一个本地 web 服务,然后自动打开包含模块文档的网页,样式非常古老,而且其中的内容都包含在下面的文档文件中了,所以基本没人会用这个。
  • Python 3.8 Manuals (64-bit),点击打开文档
  • Python 3.8 (64-bit),点击用来启动 Python 解释器。用这种方法启动解释器,退出后就整个黑窗口都消失了,打印的信息也都看不到了,所以我们一般是先启动命令行,再从命令行内启动 Python,这样即使解释器退出了,也能看到刚才程序执行的结果。

海象运算符(赋值表达式)

海象运算符 := 可在表达式内部为变量赋值,虽然官方名称叫赋值表达式,可它的昵称海象运算符更为人熟知,至于昵称的由来其实仔细观察就会发现,它很像海象的眼睛和长牙。

先举个例子:

a='abcdefg'

if len(a)>3:

print(f'字符串 {a} 的长度是 {len(a)}')

运行结果为:

可以看到,例子中的 len 函数用了两次,这种重复的运算肯定会对性能产生影响。原本我们是可以提前先把 len 函数的值算出来的,可那样又多写了一行,让代码不那么简洁。

那么我们再用海象运算符重新写一下:

a='abcdefg'

if (b:=len(a))>3:

print(f'字符串 {a} 的长度是 {b}')

运行结果如下:

可以看到, (b:=len(a)) 部分其实就是把 len(a) 算出来的值赋值到 b 了,后面我们就能直接使用 b 的值了。

需要注意的是,这里一定要用括号括起来,因为大于号 > 比海象运算符 := 优先级高,不括起来相当于先计算后面部分,然后赋值给 b 也就是 b:=(len(a)>3) 得到的 b 的值就变成布尔值了。其他一些场合不括起来还可能报错,需要注意。大家可以多多尝试,仔细体会。

下面再来一个有趣的例子,见识一下海象运算符的威力。

相信很多人都用 Python 写过斐波那契数列,使用海象运算符,你甚至可以一行代码实现。

[(f:=(f[1], sum(f)) if i else (0,1))[1] for i in range(10)]

运行结果如下:

海象运算符虽然可以在很多场合使用,但官方也建议尽量将海象运算符的使用限制在清晰的场合中,以降低复杂性并提升可读性。

仅限位置形参

新增了一个函数形参语法 / 用来指明某些函数形参必须使用仅限位置而非关键字参数的形式。/ 左侧的参数必须使用位置形参。

另外, * 的右边为仅限关键字形参。

下面的例子中,形参 a b 为仅限位置形参,c d 可以是位置形参或关键字形参,也就是默认形式,而 e f 要求为仅限关键字形参:

def f(a, b, /, c, d, *, e, f):

print(a, b, c, d, e, f)

我们尝试用关键字方式给 a b 赋值,运行结果如下:

可以看到,错误提醒很明确,我们在仅限位置参数的地方放了关键字参数。

如果你把 e f 的关键字去掉,当作位置参数使用,它也会报错。

我们按照正确的要求写入参数,运行结果如下:

另外,在 / 左侧的形参不会被公开为可用关键字,其形参名仍可在 **kwargs 中使用。

举个例子:

def f(a, b, /, **kwargs):

print(a, b, kwargs)

然后我们给后面的参数赋值给 a , b

f(10, 20, a=1, b=2, c=3)

运行结果如下:

可以看到,/ 左侧仅限位置形参的参数名并不影响后面我们后来的操作。

字典可使用 reversed 进行反转

普通字典自 Python 3.7 起已保证具有确定的元素顺序,在 Python 3.8 中可以利用 reversed 按插入顺序反向迭代。Python 字典(Dictionary) items() 函数以列表返回可遍历的(, ) 元组数组

s={'a':23,'b':24,'c':66}

list(reversed(s.items()))

运行结果如下:

f-string 增加 = 说明符

f-string 的早期版本,我们要想实现 a = x 的形式,往往比较麻烦。增加 = 说明符用于 f-string。形式为 f'{expr=}'  f 字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值结果。

name = 'Galaxy'

print(f'name = {name}')

运行结果如下:

Python3.8 更新了新的更加简洁的写法,也就是 = 说明符

name = 'Galaxy'

print(f'{name = }')

运行结果如下:

另外,新版本还给 f-string 增加了转换符 !s !a !r

转换符 '!s' 是对结果调用 str()'!r' 是调用 repr(),而 '!a' 是调用 ascii()

我们来举个例子

import datetime

today = datetime.date.today()

print(f'今天是 {today!s}')

运行结果如下:

repr() 函数将对象转化为供解释器读取的形式。

转换符'!r'的结果如下:

ascii() 函数类似 repr() 函数, 返回一个表示对象的字符串, 但是对于字符串中的非 ASCII 字符则返回通过 repr() 函数使用 \x, \u \U 编码的字符。 生成字符串类似 Python2 版本中 repr() 函数的返回值。

转换符'!a'的结果如下:

可从进程直接访问的共享内存

该模块提供了一个 SharedMemory 类,用于分配和管理多核或对称多处理器(SMP)机器上进程间的共享内存。

介绍一个有趣的新功能,它可以从进程直接访问的共享内存。

我们先打开运行下面代码,获得一个 name

from multiprocessing import shared_memory

a = shared_memory.ShareableList([2021, 'abc', 2022])

a

然后打开一个新终端

from multiprocessing import shared_memory b = shared_memory.ShareableList(name=) #这里要把获得的name值写入 b

运行结果如下:

以下示例展示了一个现实中的例子,使用 SharedMemory 类和 NumPy arrays 结合, 从两个 Python shell 中访问同一个 numpy.ndarray :

>>> # In the first Python interactive shell
>>> import numpy as np
>>> a = np.array([1, 1, 2, 3, 5, 8])  # Start with an existing NumPy array
>>> from multiprocessing import shared_memory
>>> shm = shared_memory.SharedMemory(create=True, size=a.nbytes)
>>> # Now create a NumPy array backed by shared memory
>>> b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
>>> b[:] = a[:]  # Copy the original data into shared memory
>>> b
array([1, 1, 2, 3, 5, 8])
>>> type(b)
<class 'numpy.ndarray'>
>>> type(a)
<class 'numpy.ndarray'>
>>> shm.name  # We did not specify a name so one was chosen for us
'psm_21467_46075'
 
 
>>> # In either the same shell or a new Python shell on the same machine
>>> import numpy as np
>>> from multiprocessing import shared_memory
>>> # Attach to the existing shared memory block
>>> existing_shm = shared_memory.SharedMemory(name='psm_21467_46075')
>>> # Note that a.shape is (6,) and a.dtype is np.int64 in this example
>>> c = np.ndarray((6,), dtype=np.int64, buffer=existing_shm.buf)
>>> c
array([1, 1, 2, 3, 5, 8])
>>> c[-1] = 888
>>> c
array([  1,   1,   2,   3,   5, 888])
 
 
>>> # Back in the first Python interactive shell, b reflects this change
>>> b
array([  1,   1,   2,   3,   5, 888])
 
 
>>> # Clean up from within the second Python shell
>>> del# Unnecessary; merely emphasizing the array is no longer used
>>> existing_shm.close()
 
 
>>> # Clean up from within the first Python shell
>>> del# Unnecessary; merely emphasizing the array is no longer used
>>> shm.close()
>>> shm.unlink()  # Free and release the shared memory block at the very end

总结

Python 3.8 最让大家期待的就是海象运算符,其他方面还增加仅限位置形参、字典反转、f-string = 用法,另外,很多内置方法的性能都提高了 20% - 50% ,类型提示方面也有一些更新,还是很值得更新使用的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值