python3.6新增特性
https://docs.python.org/zh-cn/3.6/whatsnew/3.6.html
新增f字符串
用法和format基本是一样的
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> "He said his name is {name}.".foramt(name=name)
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result: 12.35'
>>> "result: {value:{width}.{precision}}".format(width=width,precision=precision, value=value)
'result: 12.35'
只是把format写法精简了,更多的格式化语法可以看: https://docs.python.org/zh-cn/3.6/library/string.html#formatspec
数字中的下划线
>>> 1_0_0_0
1000
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
允许在数字之间添加下划线让代码更好看。不能再开头和结尾出现下划线,而且不能连续出现两个下划线
另外format语法也支持_
>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'
异步生成器
允许在异步函数内同时出现yield和await,也就是可以实现异步生成器
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)
异步推导式
result = [i async for i in aiter() if i % 2] result = [await fun() for fun in funcs if await condition()] 这种语法我感觉用不上
新增方法:__init_subclass__
没看懂,略
https://juejin.cn/post/6844904065302790158
新增方法:__set_name__
没看懂,略
https://www.cnblogs.com/traditional/p/11714356.html
路径支持使用对象
在之前的版本里,传入一个路径基本都是使用字符串,现在可以使用pathlib.Path("/root/1.txt")) ,它实现了__fspath__来表示实际的路径
>>> 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'
这篇文章详细的介绍了:https://zhuanlan.zhihu.com/p/87940289
路径默认编码改为utf-8
python3.5是mbcs。
>>> import sys
>>> sys.getfilesystemencoding()
'mbcs'
正常来说是没有影响的,因为操作路径一般给的都是字符串而不是字符,总不会有人这么写文件吧
with open("中国.txt".encode(), 'w') as f:
pass
https://peps.python.org/pep-0529/
Windows控制台编码改为utf-8
sys.stdin, sys.stdout和sys.stderr默认编码都是utf-8,
当然,这是Windows的cmd里面出现乱码的原因,因为cmd默认编码是gbk
cmd修改编码很简单:chcp 65001 。想改回gbkchcp 936
新的dict实现
新dict的内存使用量会比之前减少20%到25%,而且现在的字典是有序的,当然这不是刻意保留的特性,未来可能会改变
新增secrets模块
就是一些随机数或者字符串的方法,一般用不上 https://docs.python.org/zh-cn/3.6/library/secrets.html#module-secrets
python3.7新增特性
新增dataclass
顾名思义就是一个装数据的类, 会自己生成__init__ 、__repr__ 、__eq__ 和__hash__
@dataclass
class Point:
x: float
y: float
z: float = 0.0
p = Point(1.5, 2.5)
print(p)
https://www.cnblogs.com/apocelipes/p/10284346.html
新增importlib.resources
用于更好读取的import 导入的包,它不一定是文件系统内实际存在的文件或文件夹,比如在zip压缩包内等
import importlib.resources as res
import tkinter
text = res.read_text(tkinter, 'dialog.py', encoding='utf-8', errors='strict')
print(text)
https://blog.csdn.net/be5yond/article/details/120062721
python3.8
:=
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
上面的语法相当于n = len(a) 和n>10 ,只是为了len这个方法不被调用两次。当然这个例子不是很直观。
while (block := f.read(256)) != '':
process(block)
当读取到空字符串的时候就停止,如果这个改成常规写法应该是下面这样的(或者直接while True),是不是变的更简洁了
block = f.read(256)
while block != '':
process(block)
block = f.read(256)
还有一种情况是在列表推导式中 [f(x) for x in range(10) if f(x)>0] f(x)被运行了两次 [y for x in range(10) if (y:=f(x)) >0] 这样就只运行了一次
函数参数新增/ 语法
和* 类似,看例子
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
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) 是错误的
f字符串新增=语法
user = 'eric_idle'
member_since = date(1975, 7, 31)
f'{user=} {member_since=}'
具有外部数据缓冲区的 pickle 协议 5
pickle新增缓冲区来减少数据拷贝,与之前的Python版本的pickle可能存在不兼容的情况
新增importlib.metadata模块
用于读取模块的一些信息
>>> from importlib.metadata import version, requires, files
>>> version('requests')
'2.22.0'
>>> list(requires('requests'))
['chardet (<3.1.0,>=3.0.2)']
>>> list(files('requests'))[:5]
[PackagePath('requests-2.22.0.dist-info/INSTALLER'),
PackagePath('requests-2.22.0.dist-info/LICENSE'),
PackagePath('requests-2.22.0.dist-info/METADATA'),
PackagePath('requests-2.22.0.dist-info/RECORD'),
PackagePath('requests-2.22.0.dist-info/WHEEL')]
python3.9
字典之间新增| 和|= 运算符
首先给了个字典合并的几种方法
d = {'spam': 1, 'eggs': 2, 'cheese': 3}
e = {'cheese': 'cheddar', 'aardvark': 'Ethel'}
print({**d, **e})
from collections import ChainMap
print(dict(ChainMap(e, d)))
print(dict(d, **e))
d.update(e)
print(d)
然后给出了python3.9的第五种方法: print(d | e)
注意d|e 和e|d 结果(顺序和值)可能是不一样的,这和之前的四种方法一样执行有先后的顺序
虽然| 很方便,但还是无法处理所有的情况,比如print({'a': [1, 2]} | {'a': [3, 4]}) 是应该得到{'a': [1, 2, 3, 4]} 还是 {'a': [[1, 2], [3, 4]]} ,这种就只能自己写方法去实现了
字符串新增两个方法
实现如下
def removeprefix(self: str, prefix: str, /) -> str:
if self.startswith(prefix):
return self[len(prefix):]
else:
return self[:]
def removesuffix(self: str, suffix: str, /) -> str:
if suffix and self.endswith(suffix):
return self[:-len(suffix)]
else:
return self[:]
使用例子:
if test_func_name.startswith("test_"):
print(test_func_name[5:])
else:
print(test_func_name)
改为: print(test_func_name.removeprefix("test_"))
|