python3新增特性总结(3.5,3.6,3.7,3.8,3.9)

import asyncio
import numpy
import decimal
import re
import datetime
from math import radians, cos
import nest_asyncio
nest_asyncio.apply()

1.python 3.5的新增特性

01. 标准库中的改进

  • 新的subprogress.run() 方法

02. 新的语法特性

001.使用async await语法实现协程(coroutine)

如下

async def hello():
    print('hello')
await hello()

async for 可以遍历你写的异步操作的迭代器
下面是官方给出的例子, 不过不知道为什么在python3.8 jupyter notebook下不能正常执行,难道api已经弃用了?
就我去查了以下发现, "RuntimeError: This event loop is already running",这个错误其实是因为asyncio不允许事件循环的嵌套。jupyter本身的web后台已经运行了一个事件循环,所以你不能用get_event_loop开启一个新循环了。
所以我导入了一个nest-asyncio包,是这个问题的一个解决方案,之后就可以用了。

async def http_get(domain):
    reader, writer = await asyncio.open_connection(domain, 80)

    writer.write(b'\r\n'.join([
        b'GET / HTTP/1.1',
        b'Host: %b' % domain.encode('latin-1'),
        b'Connection: close',
        b'', b''
    ]))

    async for line in reader:
        print('>>>', line)

    writer.close()

loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(http_get('www.baidu.com'))
finally:
    print('finish')
#     loop.close()

async with 实现异步的上下文管理器,比如异步锁
async with lock
官方给的例子同样无法执行,太蠢了

async def coro(name, lock):
    print('coro {}: waiting for lock'.format(name))
    async with lock:
        print('coro {}: holding the lock'.format(name))
        await asyncio.sleep(1)
        print('coro {}: releasing the lock'.format(name))

loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
    loop.run_until_complete(coros)
finally:
    print('finally')
#     loop.close()

002.矩阵乘法专用的运算符@

x = numpy.ones(3)
m = numpy.eye(3)
print('x:', x)
print('m:', m)
x@m

003.新的解包操作符,可以解构字典和列表

其中*解构列表,**解构字典

print(*[1], *[2], 3, *[4, 5])


def fn(a, b, c, d):
    print(a, b, c, d)


fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})

也可以解构元祖,集合set等

*range(4), 4
[*range(4), 4]
{*range(4), 4, *(5, 6, 7)}
{'x': 1, **{'y': 2}}

03.新的库模块

  • typing 类型提示
  • zipapp 改进Python ZIP应用程序支持.

2.python 3.6的新增特性

01.新的语法特性

001.格式化字符串 PEP498

就类似于js的模板字符串,括号内的变量会在运行时求值,并且用format()进行格式化

name = 'zhangsan'
f'he said his name is {name}'
# 格式化的宽度
width = 10
# 精度,结果长度是4位
precision = 4
# decmials是进行十进制浮点数运算的模块,基于人类习惯的浮点数模型,具有精确性,比如0.1+0.1+0.1-0.3=0
value = decimal.Decimal("12.34567")
f"result: {value:{width}.{precision}}"

002.变量注释的语法 PEP526

这个语法的使用需要一些工具支持,比如pycharm

primes: list[int] = []

captain: str  # Note: no initial value!


class Starship:
    stats: dict[str, int] = {}


primes.append('sda')
print(primes)

003.数字中可以使用下划线增强可读性 PEP515

print(1_000_000_000_000_00)
print(0x_FF_FF_FF_FF)

字符串格式化也支持下划线_选项

'{:_}'.format(1000000)
'{:_x}'.format(0xFFFFFFFF)

004.异步生成器 PEP525

python3.5中存在不能再同一个函数体中使用await和yield的限制,在python3.6中已经解除,这样就可以实现异步生成器了。

async def ticker(delay, to):
    """Yield numbers from 0 to *to* every *delay* seconds."""
    for i in range(to):
        yield i
        await asyncio.sleep(delay)
# tickers =  ticker(50,100)
async for i in ticker(1, 3):
    print(i)

005.异步推导 PEP530

增加了对列表,集合和字典推导式和生成表达式中对async for的支持
await表达式也在所有种类的推导式得到了支持

result = [i async for i in aiter() if i % 2]

result = [await fun() for fun in funcs if await condition()]

006.增加文件系统路径协议 PEP519

文件路径历来都是用bytes和str来表示
大家都认定路径是这两种类型之一,问题在于阻止了路径的对象表示的库pathlib和其他库之间的使用。

定义了os.PakLick的接口,并且内置的open和os的其他模块也更新了。
这个设计使得其他第三方代码以比较少的修改,兼容pathlike对象

>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
...     contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'

007.windows系统中 文件编码和控制台编码更改为UTF-8

3.python 3.7的新增特性

01.新增的语法特性

001.延迟的标注求值(一看就知道是用不到的语法)

002.async和await成为保留关键字

02.数据模型的改进

dict 对象会保持插入时的顺序这个特性 正式宣布 成为 Python 语言官方规范的一部分。

03.标准库中的改进

time 模块现在提供 纳秒级精度函数 的支持。

4.python 3.8的新增特性

01. 新增语法特性

001.赋值表达式 PEP572
新增的语法 := 可在表达式内部为变量赋值。 它被昵称为“海象运算符”因为它很像是 海象的眼睛和长牙。

下面这个例子,避免了调用len两次的情况。
你在if里不进行赋值,直接用len(a),那么你到格式化字符串的时候还要再用一次len()计算,
这种情况我们可能会再if外先定义一个len的变量,但是这个新特性的写法显然会更简洁一些,提升可读性

a = '1234567890123'
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

类似的,下面这个正则表达式的例子

advertisement = r'80% discount '
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
    discount = float(mo.group(1)) / 100.0
    print(discount)


此运算符也适用于配合 while 循环计算一个值来检测循环是否终止,而同一个值又在循环体中再次被使用的情况:

# Loop over fixed length blocks
while (block := f.read(256)) != '':
    process(block)

另一个值得介绍的用例出现于列表推导式中,在筛选条件中计算一个值,而同一个值又在表达式中需要被使用:

[clean_name.title() for name in names
 if (clean_name := normalize('NFC', name)) in allowed_names]

002.仅限位置形参 PEP570

函数参数用/,指明某些函数形参必须使用仅限位置而非关键字参数的形式

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

以下均为合法的调用:

f(10, 20, 30, d=40, e=50, f=60)

但是,以下均为不合法的调用:

f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60)           # e must be a keyword argument

003.f字符串支持用=,自动记录表达式和调试文档

增加 = 说明符用于 f-string。 形式为 f'{expr=}' 的 f-字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值结果。

user = 'eric_idle'
member_since = datetime.date(1975, 7, 31)
f'{user=} {member_since=}'

通常的 f-字符串格式说明符 允许更细致地控制所要显示的表达式结果:

delta = datetime.date.today() - member_since
f'{user=!s}  {delta.days=:,d}'

= 说明符将输出整个表达式,以便详细演示计算过程:

theta = 30
print(f'{theta=}  {cos(radians(theta))=:.3f}')

5.python 3.9新增特性

01. 新增的语法特性

001. dict增加合并运算符

合并 (|) 与更新 (|=) 运算符已被加入内置的 dict 类。 它们为现有的 dict.update{**d1, **d2} 字典合并方法提供了补充。

x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}
print(x | y)
print(y | x)

你可能感兴趣的:(python3新增特性总结(3.5,3.6,3.7,3.8,3.9))