Python3.8新特性

目录

        • 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() 两次
# 其他1:这种调用了2次len方法
if len("海象运算符") > 3:
    print(f"limit {len('海象运算符')} elements, expected <= 3")
# 其他2::比这种更加简洁
n = len("海象运算符")
if n > 3:
    print(f"limit {n} elements, expected <= 3")   
# python3.8
if (n := len("海象运算符")) > 3:
    print(f"limit {n} elements, expected <= 3")
  • example2:正则表达式匹配中需要使用两次匹配对象的情况中,一次检测用于匹配是否发生,另一次用于提取子分组
# python3.8
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:位置参数调用、关键字参数调用 、仅限位置参数调用
# 其他1:位置参数调用、把 x 和 y 当做命名关键字参数进行传递
def add(x, y, *args, **kwargs):
    print(f"x={x}, y={y}")
add(1, 2) 
add(y=2, x=1)

# python 3.8
def add(x, y, /, *args, **kwargs):
    print(f"x={x}, y={y}")
add(1, 2)
# python3.8非法调用如下报错:
# add(y=2, x=1)
# Traceback (most recent call last):
#   File "", line 1, in 
#     add(y=2, x=1)
# TypeError: add() missing 2 required positional arguments: 'x' and 'y'
# “/“ 告诉解释器,x 和 y 是两个严格的位置参数,不能当做命名关键字参数进行传递。如果把它当作命名关键字参数进行传递参数时,就会报错,仅位置参数是不支持命名关键字参数进行传递的。
  • 位置参数,默认参数,可变参数,关键字参数,命名关键字参数
3、f-strings 说明符 =
  • f-strings 增加了 = 说明符, f’{expr=}’ 用于自动记录表达式和调试文档
  • example1:= 说明符将输出整个表达式,加一个等于号和对应结果
# python3.8
x = 3
print (f'{x+1}')  # 4
print (f'{x+1=}')  # x+1=4
4、可反转字典reversed()
  • Python已经开始从3.7开始保留dictionary中插入键的顺序,python3.8中,使用reversed()可以反转它。
  • example1:
# python3.8
dict1={
     'a':5,'b':6}
print(list(reversed(dict1))) 
# ['b', 'a']
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
# 输出如下:
# 1/0 divided...error
# 1 continue in finally
# 2/0 divided...error
# 2 continue in finally
6、新增模块importlib.metadata
  • 通过此模块,你可以访问有关Python安装中已安装软件包的信息
  • example1:比如显示当前安装的pip版本是19.2.3;此版本的pip需要Python 2.7或Python 3.5或更高版本。
from importlib import metadata
print(metadata.version("pip"))  
# '19.2.3'
pip_metadata = metadata.metadata("pip")
print(pip_metadata["Requires-Python"])
# '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*'
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()

Python3.8新特性_第1张图片

9、新语法警告
  • Python为缺少逗号引入了新的警告消息,在这个新版本中的错误消息。解释器会抛出这个有用的警告信息,这将有助于用户快速找到自己的错误。
list1=[[0,1] [2,3]] #这将给出缺少逗号和TypeError的SyntaxWarning。
# Traceback (most recent call last):
#   File "", line 1, in 
#     list1=[[0,1] [2,3]]
# TypeError: list indices must be integers or slices, not tuple
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()

# work1 nums= ShareableList([10, 11, 12, 13, 14], name='wnsm_b5d3682b')
# work2 nums= ShareableList([10, 11, 12, 13, 14], name='wnsm_b5d3682b')
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

你可能感兴趣的:(PythonKnowledge)