Python3.10新特性初体验
2021/10/12 22:15:03
本文主要是介绍Python3.10新特性初体验,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Python3.10新特性初体验
注:图片来源
目录
- 结构模式匹配 【PEP 635】
- union类型允许X | Y 【PEP 604】
- 带圆括号的上下文管理器
一、结构模式匹配(新增PEP 635)
如果你熟悉别的语言,你肯定知道switch->case
语句,python3.10之前的版本是一直没有这种语法的,但是这一次的更新中3.10+版本开始支持这种结构模式匹配的语法书写了–match->case
1、基本语法
match expression: # 条件,可为任意表达式、变量 case pattern_1: # 模式,待匹配的条件1 ... # 需要执行的代码块 case pattern_2: # 模式,待匹配的条件2 ... # 需要执行的代码块 case _: # 模式,表示default ... # 需要执行的代码块
2、模式
1. as模式(AS)
def simplify_expr(tokens): match tokens: case [('(' | '[') as l, *expr, (')' | ']') as r] if (l + r) in ('()', '[]'): # 第一个参数得为('(' | '['),取别名为l # 最后一个参数得为('(' | '['),取别名为r # 并且需判断(l + r) in ('()', '[]')为True才会进入此代码块执行 print(expr) case [0, ('+' | '-') as op, right]: # 第一个参数必须为0 # 第二个参数得为('+' | '-'),取别名为op # 第三个参数为任意数 # 序列的长度必须为3个 print(op, right) case [(int() | float()) as value]: # 序列的长度只能有1个 # 并且,类型只能是int或者float print(value) case _: # 匹配不到则走这里 print("未匹配到") simplify_expr(['(', "aaa", "bbb", ")"]) # ['aaa', 'bbb'] simplify_expr(['[', "aaa", "bbb", "]"]) # ['aaa', 'bbb'] simplify_expr(['[', "aaa", "bbb", ")"]) # 未匹配到 simplify_expr(['[', "]"]) # [] simplify_expr(['bbb', '[', "]"]) # 未匹配到 simplify_expr([0, "+", 3]) # + 3 simplify_expr([0, "-", 3]) # - 3 simplify_expr([0, "-", 3, 34]) # 未匹配到 simplify_expr([1]) # 1 simplify_expr([1.0]) # 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) # 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))) # 12 print(simplify(('+', 13, 0))) # 13 print(simplify(('-', 13, 0))) # 13 print(simplify(('and', True, 0))) # 0 print(simplify(('and', False, 0))) # False print(simplify(('or', False, 1))) # 1 print(simplify(('or', True, 1))) # True print(simplify(('not', ('not', 23)))) # 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)) # 2.5 ==> a ==> sum(a) / len(a)==> (1+2+3+4)/4 = 2.5 print(average(1, 2)) # 1.5 ==> [x, y] ==> (x+y)/2 ==> (1+2)/2=1.5 print(average(1)) # 1 ==> [x] ==> x=1 print(average()) # 0 ==> [] ==> 0 # 如果传递的是三个元素,则会按照长度进行匹配,跟传字典类型不同 print(average(1, 2, 3)) # 6 ==> [x, y, z] ==> 1+2+3=6
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)) # False ==> _ ==> False print(is_closed([1])) # True ==> [_] ==> True print(is_closed([1, 2, 3])) # False ==> [start, *_, end] ==>>1 ==3 ==>False
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"]) # 请求成功,类型是TEXT,body==>dddddd handle_reply([200, "appl_zip", "dddddd"]) # 请求成功,类型是APPL_ZIP,body==>dddddd handle_reply([200, "appl_zip", "dddddd"]) # 请求成功,类型是APPL_ZIP,body==>dddddd handle_reply([301, "sip:smith@zte.com.cn"]) # 301了,赶紧检查下URI==>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)) # False ==> _ ==> False print(is_closed([1])) # True ==> [_] ==> True print(is_closed([1, 2, 3])) # False ==> [start, *_, end] ==>>1 ==3 ==>False
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) # {'color': 'red'} change_red_to_blue(color) print(color) # {'color': 'blue'} # 注意:如果传参是字典,依次从下进行匹配,只要匹配到则不会再往下匹配了 # 如下,color包含color和children两个键,匹配时,匹配到了color就结束了,不会再进行下一步匹配children了 color = {"color": "red", "children": [{"color": "#FF0000"}]} print(color) # {'color': 'red', 'children': [{'color': '#FF0000'}]} change_red_to_blue(color) print(color) # {'color': 'blue', 'children': [{'color': '#FF0000'}]} children中的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")) # ronin ==> _ ==> MyClassA("ronin").name ==> class_.name=ronin demo(MyClassA("desire")) # 是desire啊 ==> MyClassA(name="desire") ==> print("是desire啊")
3、匹配要注意的顺序
- 当 match 的对象是一个 list 或者 tuple 的时候,需要长度和元素值都能匹配,才能命中,在
捕获模式
中体现的有。 - 当 match 的对象是一个 dict 的时候,规则却有所不同,只要 case 表达式中的 key 在所 match 的对象中有存在,即可命中,在
映射模式
中体现的有。 - 而当 match 的对象是类对象时,匹配的规则是,跟 dict 有点类似,只要对象类型和对象的属性有满足 case 的条件,就能命中,在
类模式
中体现的有。
二、union类型允许X | Y (PEP 604)
新的语法union接受函数,变量和参数注释。
1、简单的语法
# before from typing import List, Union, Optional def f(list: List[Union[int, str]], param: Optional[int]) -> Union[float, str]: pass # now 更加简洁了 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] # True
3、顺序是没有要求的
(int | str) == (str | int) # True (int | str | float) == typing.Union[str, float, int] # True
4、isinstance和issubclass支持
isinstance(5, int | str) # True isinstance("aaa", int | str) # True isinstance(1.22, int | str) # False issubclass(bool, int | float) # True isinstance(None, int | None) # True isinstance(42, None | int) # True
三、带圆括号的上下文管理器
已支持使用外层圆括号来使多个上下文管理器可以连续多行地书写。 这允许将过长的上下文管理器集能够以与之前 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
附件
参考资料文献
- https://docs.python.org/zh-cn/3.10/whatsnew/3.10.html
- https://www.python.org/dev/peps/pep-0619/#features-for-3-10
- https://github.com/python/cpython/blob/e6497fe698f6e87344501a68ffdea106eafcb257/Lib/test/test_patma.py
这篇关于Python3.10新特性初体验的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Python基础编程
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南