Python3.8的新增特性


Python3.8的新增特性

文章插图
 
Python 3.8稳定版于2019年10月14日发布,相信还有很多项目并没有升级到3.8版本,今天有一个项目经理问我:我们项目组要升级到Python3.8,3.8和3.7有什么区别呢?你能不能跟我讲一下 。我问了他为什么要升级,然后对他说:你就当3.7用就行了 。他对我说:你们肯定也要升级,你赶紧了解一下,然后给我们讲一讲 。虽然python2.7的项目我们依然在开发,但是谁知道什么时候就得必须升级了呢 。所以我就专门看了一下3.8的升级特性,在这里做一个记录 。以下为Python3.8相比3.7的新增特性 。
赋值表达式新增的语法 := 可在表达式内部为变量赋值 。它被昵称为“海象运算符”因为它很像是海象的眼睛和长牙 。
在这个示例中,赋值表达式可以避免调用 len() 两次:
if (n := len(a)) > 10:print(f"List is too long ({n} elements, expected <= 10)")类似的益处还可出现在正则表达式匹配中需要使用两次匹配对象的情况中,一次检测用于匹配是否发生,另一次用于提取子分组:
discount = 0.0if (mo := re.search(r'(d+)% discount', advertisement)):discount = float(mo.group(1)) / 100.0此运算符也适用于配合 while 循环计算一个值来检测循环是否终止,而同一个值又在循环体中再次被使用的情况:
# Loop over fixed length blockswhile (block := f.read(256)) != '':process(block)另一个值得介绍的用例出现于列表推导式中,在筛选条件中计算一个值,而同一个值又在表达式中需要被使用:
[clean_name.title() for name in names if (clean_name := normalize('NFC', name)) in allowed_names]不过这个运算符可读性不高,因此一定要使用在比较清晰的场景
仅限位置形参新增了一个函数形参语法 / 用来指明某些函数形参必须使用仅限位置而非关键字参数的形式 。这种标记语法与通过 help() 所显示的使用 Larry Hastings 的 Argument Clinic 工具标记的 C 函数相同 。
在下面的例子中,形参 a 和 b 为仅限位置形参,c 或 d 可以是位置形参或关键字形参,而 e 或 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):print(a, b, c, d, e, f)以下均为合法的调用:
【Python3.8的新增特性】f(10, 20, 30, d=40, e=50, f=60)但是,以下均为不合法的调用:
f(10, b=20, c=30, d=40, e=50, f=60)# b不能是关键字参数f(10, 20, 30, 40, 50, f=60)# e必须是关键字参数这种标记形式的一个用例是它允许纯 Python 函数完整模拟现有的用 C 代码编写的函数的行为 。例如,内置的 divmod() 函数不接受关键字参数:
def divmod(a, b, /):"Emulate the built in divmod() function"return (a // b, a % b)另一个用例是在不需要形参名称时排除关键字参数 。例如,内置的 len() 函数的签名为 len(obj, /) 。这可以排除如下这种笨拙的调用形式:
len(obj='hello')# The "obj" keyword argument impairs readability另一个益处是将形参标记为仅限位置形参将允许在未来修改形参名而不会破坏客户的代码 。例如,在 statistics 模块中,形参名 dist 在未来可能被修改 。这使得以下函数描述成为可能:
def quantiles(dist, /, *, n=4, method='exclusive')...由于在 / 左侧的形参不会被公开为可用关键字,其他形参名仍可在 **kwargs 中使用:
>>> def f(a, b, /, **kwargs):...print(a, b, kwargs)...>>> f(10, 20, a=1, b=2, c=3)# a and b are used in two ways10 20 {'a': 1, 'b': 2, 'c': 3}这极大地简化了需要接受任意关键字参数的函数和方法的实现 。例如,collections 模块的一段代码:
class Counter(dict):def __init__(self, iterable=None, /, **kwds):# Note "iterable" is a possible keyword argument用于已编译字节码文件的并行文件系统缓存新增的 PYTHONPYCACHEPREFIX 设置 (也可使用 -X pycache_prefix) 可将隐式的字节码缓存配置为使用单独的并行文件系统树,而不是默认的每个源代码目录下的 __pycache__ 子目录 。
缓存的位置会在 sys.pycache_prefix 中报告 (None 表示默认位置即 __pycache__ 子目录) 。
Python3.8的新增特性

文章插图
Python3.8之前会生成__pycache__子目录
f-字符串支持 = 用于自动记录表达式和调试文档增加 = 说明符用于 f-string 。形式为 f'{expr=}' 的 f-字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值结果 。例如:


推荐阅读