目录
-
-
-
- Python3.8主要新特性
-
- 1、 赋值表达式:=
- 2、 仅限位置参数/
- 3、f-strings 说明符 =
- 4、可反转字典reversed()
- 5、finally语句中可以有continue
- 6、新增模块importlib.metadata
- 7、PEP 578,审计钩子
- 8、Asyncio 异步交互模式
- 9、新语法警告
- 10、进程间可以共享内存
- 11、支持将编译字节码文件输出到其他位置
- 12、新版本的pickle协议
- 13、性能改进
- 14、其他改进
Python3.8主要新特性
- Python教程
- Python新变化官方文档
- Python3.8主要新功能
1、 赋值表达式:=
- :=操作符,可在表达式内部为变量赋值;即将一个值赋给一个变量,即使变量不存在也可以;提高代码简洁性。
- example1:避免调用 len() 两次
if len("海象运算符") > 3:
print(f"limit {len('海象运算符')} elements, expected <= 3")
n = len("海象运算符")
if n > 3:
print(f"limit {n} elements, expected <= 3")
if (n := len("海象运算符")) > 3:
print(f"limit {n} elements, expected <= 3")
- example2:正则表达式匹配中需要使用两次匹配对象的情况中,一次检测用于匹配是否发生,另一次用于提取子分组
if (match := re.search(r'\d', "赋值表达式123")):
print(match.group())
2、 仅限位置参数/
- 函数形参语法 / ,指明/左侧形参必须使用仅限位置而非关键字参数的形式;以解决Python函数定义中哪个参数是位置参数、哪个参数是关键字参数的模糊性。
- example1: /使得a 和 b 是仅位置参数,只能在位置上传递,而不能使用关键字参数; c 和 d 既可以是位置参数又可以是关键字参数;e 和 f 必须是关键字参数;
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
- example2:位置参数调用、关键字参数调用 、仅限位置参数调用
def add(x, y, *args, **kwargs):
print(f"x={x}, y={y}")
add(1, 2)
add(y=2, x=1)
def add(x, y, /, *args, **kwargs):
print(f"x={x}, y={y}")
add(1, 2)
- 位置参数,默认参数,可变参数,关键字参数,命名关键字参数
3、f-strings 说明符 =
- f-strings 增加了 = 说明符, f’{expr=}’ 用于自动记录表达式和调试文档
- example1:= 说明符将输出整个表达式,加一个等于号和对应结果
x = 3
print (f'{x+1}')
print (f'{x+1=}')
4、可反转字典reversed()
- Python已经开始从3.7开始保留dictionary中插入键的顺序,python3.8中,使用reversed()可以反转它。
- example1:
dict1={
'a':5,'b':6}
print(list(reversed(dict1)))
5、finally语句中可以有continue
- try-except-finally, finally语句中使用continue合规
- example1:
for num in range(1, 3):
try:
print(num/0)
except:
print(f"{num}/0 divided...error")
finally:
print(f"{num} continue in finally")
continue
6、新增模块importlib.metadata
- 通过此模块,你可以访问有关Python安装中已安装软件包的信息
- example1:比如显示当前安装的pip版本是19.2.3;此版本的pip需要Python 2.7或Python 3.5或更高版本。
from importlib import metadata
print(metadata.version("pip"))
pip_metadata = metadata.metadata("pip")
print(pip_metadata["Requires-Python"])
7、PEP 578,审计钩子
- 可以在debug的时候解决很多疑难杂症,或者对一些非法操作进行取消,也可以用来对运行时的监控
- 目前支持审计的函数也不多,具体可以去https://www.python.org/dev/peps/pep-0578/查看,内置的操作包括exec,eval,import, open,socket等等, urllib.Request是其中之一。
- example1:在我们对www.baidu.com发起请求以后,他将调用栈以及参数全部打印出来了
import sys
import urllib.request
def audit_hook(event, args):
print(event, args)
sys.addaudithook(audit_hook)
urllib.request.urlopen('http://www.baidu.com')
pickle.find_class ('idlelib.rpc', 'unpickle_code')
exec (<code object <module> at 0x000000000299C870, file "", line 1>,)
urllib.Request ('http://www.baidu.com', None, {
}, 'GET')
import ('encodings.idna', None, ['', 'D:\\Software\\python38\\Lib\\idlelib', 'D:\\Software\\python38\\python38.zip', 'D:\\Software\\python38\\DLLs', 'D:\\Software\\python38\\lib', 'D:\\Software\\python38', 'D:\\Software\\python38\\lib\\site-packages'], [<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>], [<class 'zipimport.zipimporter'>, <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x0000000001CDEDC0>])
open ('D:\\Software\\python38\\lib\\encodings\\__pycache__\\idna.cpython-38.pyc', 'r', 32896)
exec (<code object <module> at 0x00000000029ADB30, file "D:\Software\python38\lib\encodings\idna.py", line 3>,)
import ('stringprep', None, ['', 'D:\\Software\\python38\\Lib\\idlelib', 'D:\\Software\\python38\\python38.zip', 'D:\\Software\\python38\\DLLs', 'D:\\Software\\python38\\lib', 'D:\\Software\\python38', 'D:\\Software\\python38\\lib\\site-packages'], [<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>], [<class 'zipimport.zipimporter'>, <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x0000000001CDEDC0>])
open ('D:\\Software\\python38\\lib\\__pycache__\\stringprep.cpython-38.pyc', 'r', 32896)
exec (<code object <module> at 0x0000000002CDBDF0, file "D:\Software\python38\lib\stringprep.py", line 2>,)
import ('unicodedata', None, ['', 'D:\\Software\\python38\\Lib\\idlelib', 'D:\\Software\\python38\\python38.zip', 'D:\\Software\\python38\\DLLs', 'D:\\Software\\python38\\lib', 'D:\\Software\\python38', 'D:\\Software\\python38\\lib\\site-packages'], [<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>], [<class 'zipimport.zipimporter'>, <function FileFinder.path_hook.<locals>.path_hook_for_FileFinder at 0x0000000001CDEDC0>])
import ('unicodedata', 'D:\\Software\\python38\\DLLs\\unicodedata.pyd', None, None, None)
socket.getaddrinfo ('www.baidu.com', 80, 0, 1, 0)
socket.connect (<socket.socket fd=492, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>, ('180.101.49.12', 80))
<http.client.HTTPResponse object at 0x00000000029A9760>
8、Asyncio 异步交互模式
- 在之前版本的 Python 交互模式中(REPL),涉及到 Asyncio 异步函数,通常需要使用 asyncio.run(func()) 才能执行。而在 3.8 版本中,当使用 python -m asyncio 进入交互模式,则不再需要 asyncio.run。
- example1:
import asyncio
async def test():
await asyncio.sleep(1)
return 'test'
await test()
9、新语法警告
- Python为缺少逗号引入了新的警告消息,在这个新版本中的错误消息。解释器会抛出这个有用的警告信息,这将有助于用户快速找到自己的错误。
list1=[[0,1] [2,3]]
10、进程间可以共享内存
- 在Python 3.8中,multiprocessing模块提供了SharedMemory类,可以在不同的Python进城之间创建共享的内存区域。
- 在旧版本的Python中,进程间共享数据只能通过写入文件、通过网络套接字发送,或采用Python的pickle模块进行序列化等方式。共享内存提供了进程间传递数据的更快的方式,从而使得Python的多处理器和多内核编程更有效率。
- example1:以下代码中work1与work2虽然运行在两个进程中,但都可以访问和修改同一个ShareableList对象。
from multiprocessing import Process
from multiprocessing import shared_memory
share_nums = shared_memory.ShareableList(range(5))
def work1(nums):
for i in range(5):
nums[i] += 10
print(f'work1 {nums= }')
def work2(nums):
print(f'work2 {nums= }')
if __name__ == '__main__':
p1 = Process(target=work1, args=(share_nums, ))
p1.start()
p1.join()
p2 = Process(target=work2, args=(share_nums, ))
p2.start()
11、支持将编译字节码文件输出到其他位置
- Python在运行的时候会生成对应代码的编译字节码文件,就是我们常见的.pyc文件。在Python3中,这些文件被放置在跟对应.py文件同级目录下的__pycache__文件夹下。
- 在Python3.8中,可以通过设置环境变量 PYTHONPYCACHEPREFIX(也可使用 -X pycache_prefix) 指定一个路径,让.pyc文件放在我们指定的路径下面,以此来实现.py文件和编译字节码的分离。在代码中可以通过 sys.pycache_prefix 查看生成的位置(None 表示默认位置即 pycache 子目录)。
12、新版本的pickle协议
- Python的pickle模块提供了一种序列化和反序列化Python数据结构或实例的方法,可以将字典原样保存下来供以后读取。不同版本的Python支持的pickle协议不同,而最新版本的支持范围更广、更强大、更有效的序列化。
- Python 3.8引入的第5版pickle协议可以用一种新方法pickle对象,它能支持Python的缓冲区协议,如bytes、memoryviews或Numpy array等。新的pickle避免了许多在pickle这些对象时的内存复制操作。
- pickle 现在默认使用协议4,提高了性能
13、性能改进
- 许多内置方法和函数的速度都提高了20%~50%,因为之前许多函数都需要进行不必要的参数转换。
- operator.itemgetter()也就是取元素的操作符,现在快了33%。
- collections.namedtuple()命名元组,比以前快了两倍。
- list构造器,如果输入的可迭代对象的长度是已知的,现在就不会过多的分配底层的缓冲区了,这让创建一个List比以前快了12% 。
- uuid.UUID 现在使用插槽来减少内存占用。
- 一些简单的内置和方法的调用现在快了20-50%。
14、其他改进
- PEP 587: Python 初始化配置
- PEP 590: Vectorcall,用于 CPython 的快速调用协议
- typed_ast 被合并回 CPython
- LOAD_GLOBAL 速度加快了 40%
- Python自带的测试框架unittest 加入了异步支持
- 在 Windows 上,默认 asyncio 事件循环现在是 ProactorEventLoop
- 在 macOS 上,multiprocessing 启动方法默认使用 spawn
- 详细见What’s New in Python3.8