zwvista

导航

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

Is there a difference between "==" and "is"?

posted on 2025-09-30 09:48  zwvista  阅读(7)  评论(0)    收藏  举报