Python3.10新特性初体验
注:图片来源
目录
- 结构模式匹配 【PEP 635】
- union类型允许X | Y 【PEP 604】
- 带圆括号的上下文管理器
如果你熟悉别的语言,你肯定知道switch->case 语句,python3.10之前的版本是一直没有这种语法的,但是这一次的更新中3.10+版本开始支持这种结构模式匹配的语法书写了–match->case
1、基本语法
match expression:
case pattern_1:
...
case pattern_2:
...
case _:
...
2、模式
1. as模式(AS)
def simplify_expr(tokens):
match tokens:
case [('(' | '[') as l, *expr, (')' | ']') as r] if (l + r) in ('()', '[]'):
print(expr)
case [0, ('+' | '-') as op, right]:
print(op, right)
case [(int() | float()) as value]:
print(value)
case _:
print("未匹配到")
simplify_expr(['(', "aaa", "bbb", ")"])
simplify_expr(['[', "aaa", "bbb", "]"])
simplify_expr(['[', "aaa", "bbb", ")"])
simplify_expr(['[', "]"])
simplify_expr(['bbb', '[', "]"])
simplify_expr([0, "+", 3])
simplify_expr([0, "-", 3])
simplify_expr([0, "-", 3, 34])
simplify_expr([1])
simplify_expr([1.0])
simplify_expr([1.0, 1])
simplify_expr(["aaaa"])
2. or模式(|)
def demo(code):
match code:
case 200:
print("200成功了")
case 400 | 404:
print("出问题了")
case (1002 | 1006, 200):
print("接口请求成功")
case _:
print("匹配不到")
demo(200)
demo(400)
demo(404)
demo((1006, 200))
demo(502)
3. 文字模式(Literal)
def simplify(expr):
match expr:
case ('+', 0, x):
return x
case ('+' | '-', x, 0):
return x
case ('and', True, x):
return x
case ('and', False, x):
return False
case ('or', False, x):
return x
case ('or', True, x):
return True
case ('not', ('not', x)):
return x
return expr
print(simplify(('+', 0, 12)))
print(simplify(('+', 13, 0)))
print(simplify(('-', 13, 0)))
print(simplify(('and', True, 0)))
print(simplify(('and', False, 0)))
print(simplify(('or', False, 1)))
print(simplify(('or', True, 1)))
print(simplify(('not', ('not', 23))))
4. 捕获模式(Capture)
def average(*args):
match args:
case [x, y]:
return (x + y) / 2
case [x]:
return x
case []:
return 0
case [x, y, z]:
return x + y + z
case a:
return sum(a) / len(a)
print(average(1, 2, 3, 4))
print(average(1, 2))
print(average(1))
print(average())
print(average(1, 2, 3))
5. 通配符模式(Wildcard)
- _:在前面就表示任意字符
- case _:这里的_在末尾,表示default默认
def is_closed(sequence):
match sequence:
case [_]:
return True
case [start, *_, end]:
return start == end
case _:
return False
print(is_closed(1))
print(is_closed([1]))
print(is_closed([1, 2, 3]))
6. 值模式(value)
class HttpStatus(object):
OK = 200
MOVED_PERMANENTLY = 301
NOT_FOUND = 404
class MimeType(object):
TEXT = "text"
APPL_ZIP = "appl_zip"
def handle_reply(reply):
match reply:
case (HttpStatus.OK, MimeType.TEXT, body):
print(f"请求成功,类型是TEXT,body==>{body}")
case (HttpStatus.OK, MimeType.APPL_ZIP, body):
print(f"请求成功,类型是APPL_ZIP,body==>{body}")
case (HttpStatus.MOVED_PERMANENTLY, new_URI):
print(f"301了,赶紧检查下URI==>{new_URI}")
case (HttpStatus.NOT_FOUND):
print("网站挂了。。。")
handle_reply([200, "text", "dddddd"])
handle_reply([200, "appl_zip", "dddddd"])
handle_reply([200, "appl_zip", "dddddd"])
handle_reply([301, "sip:smith@zte.com.cn"])
handle_reply(404)
7. 组织模式(Group)
使用or模式实现
def demo(code):
match code:
case 200:
print("200成功了")
case 400 | 404:
print("出问题了")
case (1002 | 1006, 200):
print("接口请求成功")
case _:
print("匹配不到")
demo((1006, 200))
8. 序列模式(Sequence)
def is_closed(sequence):
match sequence:
case [_]:
return True
case [start, *_, end]:
return start == end
case _:
return False
print(is_closed(1))
print(is_closed([1]))
print(is_closed([1, 2, 3]))
9. 映射模式(Mapping)
def change_red_to_blue(json_obj):
match json_obj:
case {'color': ('red' | '#FF0000')}:
json_obj['color'] = 'blue'
case {'children': children}:
for child in children:
change_red_to_blue(child)
color = {"color": "red"}
print(color)
change_red_to_blue(color)
print(color)
color = {"color": "red", "children": [{"color": "#FF0000"}]}
print(color)
change_red_to_blue(color)
print(color)
10. 类模式(Class)
class MyClassA(object):
def __init__(self, name) -> None:
self.name = name
def demo(class_):
match class_:
case MyClassA(name="desire"):
print("是desire啊")
case _:
print(class_.name)
demo(MyClassA("ronin"))
demo(MyClassA("desire"))
3、匹配要注意的顺序
- 当 match 的对象是一个 list 或者 tuple 的时候,需要长度和元素值都能匹配,才能命中,在
捕获模式 中体现的有。 - 当 match 的对象是一个 dict 的时候,规则却有所不同,只要 case 表达式中的 key 在所 match 的对象中有存在,即可命中,在
映射模式 中体现的有。 - 而当 match 的对象是类对象时,匹配的规则是,跟 dict 有点类似,只要对象类型和对象的属性有满足 case 的条件,就能命中,在
类模式 中体现的有。
二、union类型允许X | Y (PEP 604)
新的语法union接受函数,变量和参数注释。
1、简单的语法
from typing import List, Union, Optional
def f(list: List[Union[int, str]], param: Optional[int]) -> Union[float, str]:
pass
from typing import List
def f(list: List[int | str], param: int | None) -> float | str:
pass
2、typing.Union 和 | 是等价的
int | str == typing.Union[int, str]
3、顺序是没有要求的
(int | str) == (str | int)
(int | str | float) == typing.Union[str, float, int]
4、isinstance和issubclass支持
isinstance(5, int | str)
isinstance("aaa", int | str)
isinstance(1.22, int | str)
issubclass(bool, int | float)
isinstance(None, int | None)
isinstance(42, None | int)
三、带圆括号的上下文管理器
已支持使用外层圆括号来使多个上下文管理器可以连续多行地书写。 这允许将过长的上下文管理器集能够以与之前 import 语句类似的方式格式化为多行的形式。 一下四种格式都是支持的
with open("readme.md", 'r') as f:
pass
with (open("readme.md", 'r') as f):
pass
with (open("readme.md", 'r') as f1,
open("readme.md", 'r') as f2):
pass
with (open("readme.md", 'r'),
open("readme.md", 'r') as f2):
pass
with (open("readme.md", 'r'),
open("readme.md", 'r'),
):
pass
附件
参考资料文献
|