Python3.9 新特性

简介

Python3.9 发布于2020年10月5日,这儿总结一下改版本引入的一些新功能

官方新特性链接 Python3.9 新特性

安装

此处主要介绍在Ubuntu下安装 Python3.9

  1. 添加deadsnakes源
    • sudo add-apt-repository ppa:deadsnakes/ppa
    • sudo apt-get update
  2. 安装 Python3.9
    • sudo apt install python3.9-full
  3. 安装 Python3.9 的pip
    • python3.9 -m ensurepip --upgrade

字典合并与更新运算符

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}

# 合并
# z = {**x, **y}
z = x | y
# 如果两个字典都存在key,则保留后面的key的值,
# z: {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}

# 更新
# x.update(y)
x |= y
# x: {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
# 将y中的值更新到x中

放宽对装饰器的语法限制

在之前版本的 Python 中对于装饰器的语法是有所限制的,Python 3.9 终于将这一限制放宽任意,任何表达式都可以用在装饰器中。

之前的装饰器语法

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE

Python3.9 的装饰器语法

decorator: '@' namedexpr_test NEWLINE

旧版装饰器

1
2
3
4
5
6
7
8
9
10
11
def upper(func):
def wrapper(*args):
return func(*args).upper()
return wrapper

@upper
def hello(name):
return f'hello {name}'

hello('johnson')
# HELLO JOHNSON

新版装饰器

1
2
3
4
5
6
@lambda func:(lambda *args:func(*args).upper())
def hello(name):
return f'hello {name}'

hello('johnson')
# HELLO JOHNSON

新增用于移除前缀和后缀的字符串方法

增加了 str.removeprefix(prefix)str.removesuffix(suffix) 用于方便地从字符串移除不需要的前缀或后缀。另外 bytesbytearray 以及 collections.UserString 也增加了对应的方法

1
2
3
4
str_hello = 'hello, world!'
no_prefix = str_hello.removeprefix('hello,')
no_suffix = str_hello.removesuffix('world!')
# 该方法不会修改原始字符串,只会返回新的字符串

标准多项集中的类型标注泛型

dictlistsettuple 用于取代 typing 中的 DictListSetTuple

之前的版本

1
2
3
4
5
from typing import List

def greet_all(names: List[str]) -> None:
for name in names:
print("Hello", name)

Python3.9 版本

1
2
3
def greet_all(names: list[str]) -> None:
for name in names:
print("Hello", name)

file 属性将是一个绝对路径

1
2
3
4
5
6
7
8
# /home/stolen/test.py
print(__file__)

# Python3.8 输出
# test.py

# Python3.9 输出
# /home/stolen/test.py

datetime 模块的改进

isocalendar() 方法现在返回 namedtuple (具名元组) ,这样可以通过属性也能访问到该值

1
2
3
4
5
6
7
8
9
10
11
import datetime

today = datetime.date.today().isocalendar()
print(today)

# Python3.8
# (2022, 38, 1)

# Python3.9
# datetime.IsoCalendarDate(year=2022, week=38, weekday=1)
# today.week -> 38

math 模块的改进

math.gcd(*integers) 求最大公约数的函数允许传入超过2个参数

1
2
3
4
5
6
7
8
9
10
import math

result = math.gcd(6, 9, 12, 15, 18)
print(result)

# Python3.8
# TypeError: gcd expected 2 arguments, got 5

# Python3.9
# 3

math.lcm(*integer) 新增计算最小公倍数函数

1
2
3
4
5
6
7
8
9
10
import math

result = math.lcm(6, 9, 12, 15, 18)
print(result)

# Python3.8
# AttributeError: module 'math' has no attribute 'lcm'

# Python3.9
# 180