Python 3 学习笔记(4)
Python 3.13
match 语句
Python 的 match 语句类似于 Rust 或 Haskell 中的模式匹配
- 可以与一个或多个字面量进行比较
- 存在通配符 _
- 存在或运算符 |
- 解包赋值的模式可被用于绑定变量
- 可以用类似类构造器的形式,把属性捕获到变量里
- 捕获类的属性时也可以使用位置参数,但是需要在类中设置特殊属性
__match_args__ - 模式可以任意嵌套
- 可以为模式添加 if 作为守卫子句
- 使用 as 关键字可以捕获子模式
# 字面量
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"
# 或运算符
case 401 | 403 | 404:
return "Not allowed"
# 解包模式
# point 是一个 (x, y) 元组
match point:
case (0, 0):
print("Origin")
case (0, y):
print(f"Y={y}")
case (x, 0):
print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")
case _:
raise ValueError("Not a point")
# 捕获类的属性
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def where_is(point):
match point:
case Point(x=0, y=0):
print("Origin")
case Point(x=0, y=y):
print(f"Y={y}")
case Point(x=x, y=0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
# 使用位置参数
class Point:
__match_args__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
# 模式嵌套
match points:
case []:
print("No points")
case [Point(0, 0)]:
print("The origin")
case [Point(x, y)]:
print(f"Single point {x}, {y}")
case [Point(0, y1), Point(0, y2)]:
print(f"Two on the Y axis at {y1}, {y2}")
case _:
print("Something else")
# 守卫子句
match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
case Point(x, y):
print(f"Not on the diagonal")
# 子模式
case (Point(x1, y1), Point(x2, y2) as p2): ...
classmethod 和 staticmethod
类的非实例方法有两种:类方法和静态方法
- 两者都是 decorator
- 两者都可以通过类对象或实例对象来调用
- 调用类方法时传递类对象,因此子类可以覆盖父类的类方法
- 调用静态方法时不传递类对象
class C:
@classmethod
def class_f(cls, arg1, arg2): ...
class C:
@staticmethod
def static_f(arg1, arg2, argN): ...
C.class_f()
C().class_f()
C.static_f()
C().static_f()
数字分隔符 _
可以用 _ 来分隔较长的数字
>>> amount = 10_000_000.0
>>> amount
10000000.0
海象运算符 :=
海象运算符 := 可以将赋值表达式嵌入一个大的表达式中
values = [1, 2, 3, 4, 5, 6]
if (n := len(values)) > 5:
print(f'The list is longer than 5. It contains {n} values.')
# 相当于
...
n = len(values)
if n > 5:
...
f-字符串
f-字符串在 Python 中实现了字符串插值
- 前缀为 f 或 F
- 通过 {expression} 将值插入字符串
- {expression:format} 表示按指定格式来格式化表达式的值
a = 123
b = 'abc'
print(f'{a} and {b}')
# 123 and abc
s = 'abc'
print(f'right : {s:*>8}')
# right : *****abc
i = 1234
print(f'zero padding: {i:08}')
# zero padding: 00001234
a = 3
b = 4
print(f'{a} + {b} = {a + b}')
# 3 + 4 = 7
i = 123
print(f'{i=}')
# i=123
类型提示
在 Python 代码中添加类型提示有助于
- 提高代码可读性
- 加强 IDE 的功能(代码补全,重构等)
类型提示在运行期被无视,不起作用,对代码运行没有影响
# 变量的类型提示
name: str = "Alice"
age: int = 30
# 函数的类型提示
def greet(name: str) -> None:
print(f"Hello, {name}")
def add(a: float, b: float) -> float:
return a + b
# 序列类型的类型提示
a: list[int] = [1,2,3]
b: tuple[int] = (1,2,3)
a: dict[str, int] = {'a': 1, 'b': 2}
# 函数类型的类型提示
from typing import Callable
f: Callable[[int, int], int] = lambda a,b: a + b
不变类型和可变类型
Python 类型的不变和可变指的是类型内部元素的值的可变性
不变类型有 int float str tuple
可变类型有 list set dict
a = [1,2,3]
a[0] = 4 # ok
b = (1,2,3)
b[0] = 4 # error
def add_item(lst):
lst.append(100)
my_list = [1, 2, 3]
add_item(my_list)
print(my_list) # [1, 2, 3, 100]
def add_value(num):
num += 100
my_num = 50
add_value(my_num)
print(my_num) # 50
Python's Mutable vs Immutable Types: What's the Difference?
引用比较和值比较
对象之间的比较操作可分为值比较和引用比较
值比较使用 == 运算符
引用比较使用 is 运算符
引用比较即比较对象的 id
| 值比较 | 引用比较 | |
|---|---|---|
| Python | a == b | a is b |
| Java | Objects.equals(a, b) a.equals(b) |
a == b |
| C# | object.Equals(a, b) a == b(值类型) |
object.ReferenceEquals(a, b) a == b(引用类型) |
| Swift | a == b | a === b |
| Kotlin | a == b | a === b |
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(id(a)) # 2238458115712
print(id(b)) # 2238458107328
print(id(c)) # 2238458115712
print(a == b) # True
print(a is b) # False
print(a == c) # True
print(a is c) # True
浙公网安备 33010602011771号