python3.10 新的特性介绍
文章目录
- python3.10 新的特性介绍
- with 嵌套语句的使用 新增
- Match case 语句 新增
- 匹配对象
- 匹配状态码
- 匹配枚举类型的变量
- 或操作符新的含义
- 其他
- 参考文档
Python3.10 发布也有一段时间了,新的版本提供了一些好用的功能,可能比较关注的就是 match case
这个多分支选择语法。 以及 with 语句 的改进等。
with 嵌套语句的使用 新增
with 语句 可以同时 进行 多个 with ,打开多个上下文管理器。
import os
import os.path
from typing import List
# 源路径
src_path = r'C:\Users\XXX\XXXX\XXX\XXXXX'
# 目标路径
dst_path = r'C:\Users\AAA\BBBB\CCCC'
def get_filelist(path: str) -> List:
"""
返回 当前路径下面所有的文件名称
:param path:
:return:
"""
results = []
for home, dirs, files in os.walk(path):
for filename in files:
ab_path = os.path.join(home, filename)
results.append(ab_path)
return results
def add_head_footer(xml_string: str):
"""
add lncr head and footer
"""
head = 'this is head'
footer = 'this is footer'
return head + xml_string + footer
# python.3.10 以前的写法
def add_header_xml():
src_files = get_filelist(src_path)
for full_file in src_files:
file_name = os.path.basename(full_file)
with open(os.path.join(dst_path, file_name), 'w', encoding='utf-8') as f:
with open(os.path.join(src_path, file_name), 'r', encoding='utf-8') as fout:
src_xml = fout.read()
head_string = add_head_footer(src_xml)
try:
f.write(head_string)
except (UnicodeError, UnicodeEncodeError) as e:
print(f"file_name :{file_name},e:{e}")
print(f"{file_name} deal done.")
如果使用with 嵌套语句, 在with 可以打开多个文件, 一个作为源, 一个作为写入的文件。
下面是在python3.10 解释器下面
# python.3.10 的写法
def add_header_xml():
src_files = get_filelist(src_path)
for full_file in src_files:
file_name = os.path.basename(full_file)
with (
open(os.path.join(dst_path, file_name), 'w', encoding='utf-8') as f,
open(os.path.join(src_path, file_name), 'r', encoding='utf-8') as fout,
):
src_xml = fout.read()
head_string = add_head_footer(src_xml)
try:
f.write(head_string)
except (UnicodeError,UnicodeEncodeError) as e:
print(f"file_name :{file_name},e:{e}")
print(f"{file_name} deal done." )
是不是看起来比以前 舒服一些了呢。
Match case 语句 新增
PEP 634: Structural Pattern Matching
千呼万唤始出来, 终于python 也出现了 其他语言中 switch 语句的功能, python 使用的是 match case
语法来完成多分支选择 。
匹配对象
from dataclasses import dataclass
from enum import Enum
@dataclass
class Point:
x: int
y: int
def location(point:Point):
match point:
case Point(x=0, y=0):
print("Origin is the point's location.")
case Point(x=0, y=y):
print(f"Y={y} and the point is on the y-axis.")
case Point(x=x, y=0):
print(f"X={x} and the point is on the x-axis.")
case Point():
print("The point is located somewhere else on the plane.")
case _:
print("Not a point")
if __name__ == '__main__':
p = Point(x=1,y=0)
location(p)
甚至可以嵌套
from dataclasses import dataclass
from enum import Enum
from typing import List
@dataclass
class Point:
x: int
y: int
def location(points:List[Point] ):
match points:
case []:
print("No points in the list.")
case [Point(0, 0)]:
print("The origin is the only point in the list.")
case [Point(x, y)]:
print(f"A single point {x}, {y} is in the list.")
case [Point(0, y1), Point(0, y2)]:
print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
case _:
print("Something else is found in the list.")
if __name__ == '__main__':
pass
p = Point(x=0,y=1)
p2 = Point(x=0,y=2)
location([p,p2]) # Two points on the Y axis at 1, 2 are in the list.
p = Point(x=1,y=3)
location([p]) # A single point 1, 3 is in the list.
location([]) # No points in the list.
在case
中也可以添加 一些判断条件。 比如 x==y
, x>y
match point:
case Point(x, y) if x == y:
print(f"The point is located on the diagonal Y=X at {x}.")
case Point(x, y):
print(f"Point is not on the diagonal.")
匹配状态码
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
if __name__ == '__main__':
print(http_error('400'))
print(http_error(400))
如果要匹配多个状态码 ,可以使用 |
或 运算符来完成。
case 401 | 403 | 404:
return "Not allowed"
匹配枚举类型的变量
如果匹配 条件中有一部分重合的条件,从上到下匹配, 先匹配成功之后,进入对应的case ,其他的case 语句 将不会进入了。 case _
如果没有前面都没有匹配到, 这个是兜底策略,一定会进入这个 case 语句。
class Color(Enum):
RED = 0
GREEN = 1
BLUE = 2
BLACK = 3
def which_color(color):
match color:
case Color.RED:
print("I see red!")
case Color.BLUE|Color.GREEN:
print("I'm feeling the blues.")
case Color.GREEN:
print("Grass is green")
case _ :
print("Sorry, I'm not find color.")
if __name__ == '__main__':
pass
color = Color.GREEN
which_color(color) # I'm feeling the blues
color = Color.BLACK
which_color(color) # Sorry, I'm not find color.
或操作符新的含义
在Python 3.10中, |
符号有的新语法,可以表示x类型 或 Y类型,以取代之前的typing.Union 完成类型注解.
在3.10 以前写 参数注解,如果参数中有可能有两种类型, 就需要使用 Union
来指定类型。
例如:
from typing import Union
def double(value: Union[int, str]) -> Union[int, str]:
return value*2
现在可以使用 |
来指定类型
def double(value: str | int) -> str | int:
return value * 2
if __name__ == '__main__':
print(double('name'))
print(double(10))
这个新的定义也可以使用在 isinstance() and issubclass() 函数中。
>>> isinstance(5,int|str|dict)
True
其他
报错更加明确以及 精确到行的报错,指出对应的行数,以及对一些模块的性能提升。
参考文档
分享快乐,留住感动. '2022-02-08 21:24:26' --frank