学习python 2.语法速览

基础语法

变量与类型

python 复制代码
x = 1
x = "hello"            # 变量可重新赋不同类型的值

1 + "1"                # TypeError:不同类型不能直接相加
1 + int("1")           # 2:先显式转换

name: str = "Alice"   # 类型注解供检查器使用,运行时不自动校验
python 复制代码
# 单行注释
"""多行字符串;放在模块、类或函数开头时可作说明文档。"""

from app.routers.items import router  # 从 app/routers/items.py 导入 router

运算与判断

python 复制代码
7 / 2          # 3.5:普通除法
7 // 2         # 3:向下取整
-7 // 2        # -4:不是向零截断
7 % 2          # 1:取余

count = 0
count += 1     # Python 没有 ++
0 < count < 10 # 链式比较

name, price = "键盘", 199.0
f"{name}:{price:.2f} 元"  # '键盘:199.00 元'
python 复制代码
a, b = [1, 2], [1, 2]
a == b          # True:比较值
a is b          # False:比较是否为同一个对象

result = None
result is None  # 判断 None 用 is,不用 ==

条件与循环

python 复制代码
score = 85
if score >= 90:
    level = "优秀"
elif score >= 60:
    level = "及格"
else:
    level = "不及格"  # 冒号后用一致的缩进(通常 4 个空格)

for index, item in enumerate(["a", "b"]):
    print(index, item)  # 0 a、1 b

label = "正数" if score > 0 else "非正数"

常用数据类型

容器

python 复制代码
nums = [1, 2, 3]              # list:可修改
point = (1, 2)               # tuple:不可修改
user = {"name": "Alice"}     # dict:键值对
tags = {"python", "fastapi"} # set:不重复的元素

user["name"]                  # 'Alice';键不存在会抛 KeyError
user.get("age", 0)            # 0:键不存在时返回默认值

empty_set = set()             # {} 是空 dict,不是空 set
one_item = (42,)              # 单元素 tuple 要写逗号
python 复制代码
names = ["Ada", "Bob"]
names.append("Eve")
names[0:2]                    # ['Ada', 'Bob']:切片不含右边界

unique = set(names)
sorted(unique)                # set 无固定顺序;需要排序用 sorted()

类型注解与转换

python 复制代码
uid: int = 1
nickname: str | None = None
ids: list[int] = [1, 2]
scores: dict[str, int] = {"Ada": 100}

isinstance(uid, int)   # True:类型判断也涵盖子类
int("42")              # 42;转换失败会抛 ValueError
int(3.9)               # 3:截断,不是四舍五入

# 注解本身不拦截错误赋值;用 mypy 检查。
# FastAPI / Pydantic 会读取注解来校验请求数据。

函数与推导式

定义、调用与返回

python 复制代码
def add(a: int, b: int = 0) -> int:
    return a + b

add(1)         # 1:使用默认参数
add(1, b=2)    # 3:位置参数在前,关键字参数在后


def split_name(full_name: str) -> tuple[str, str]:
    first, last = full_name.split(" ", maxsplit=1)
    return first, last

first, last = split_name("Ada Lovelace")  # 多值返回本质是 tuple 解包

可变默认值:用 None 代替

python 复制代码
# 不要写 def add_item(item, items=[]):多次调用会共享同一个列表。
def add_item(item: int, items: list[int] | None = None) -> list[int]:
    if items is None:
        items = []
    items.append(item)
    return items

推导式与生成器

python 复制代码
squares = [n * n for n in range(5) if n % 2 == 0]  # [0, 4, 16]
lengths = {word: len(word) for word in ["hi", "python"]}

numbers = (n * n for n in range(3))  # 生成器:按需产出
list(numbers)                        # [0, 1, 4]
list(numbers)                        # []:遍历后耗尽

类与 dataclass

普通类

python 复制代码
class User:
    def __init__(self, name: str) -> None:
        self.name = name  # self 表示当前实例

    def greet(self) -> str:
        return f"你好,{self.name}"


class Admin(User):
    def __init__(self, name: str, level: int) -> None:
        super().__init__(name)  # 子类自行定义 __init__ 时,按需初始化父类
        self.level = level


Admin("Ada", 1).greet()  # '你好,Ada'

dataclass:自动生成常用方法

python 复制代码
from dataclasses import dataclass, field

@dataclass
class Item:
    name: str
    price: float
    tags: list[str] = field(default_factory=list)  # 每个实例独立的列表

item = Item("键盘", 199.0)
print(item)                 # 自动生成便于调试的 __repr__
item == Item("键盘", 199.0) # True:默认按字段比较

异常与资源管理

python 复制代码
try:
    value = int("abc")
except ValueError as exc:
    print(f"转换失败:{exc}")

with:用完自动清理

with 对象 as 变量: 用于文件等支持上下文管理的资源。进入代码块时获取资源,退出时自动清理;即使块内抛异常也会执行清理,但异常通常仍会向外抛出。

python 复制代码
# 假设 notes.txt 已存在
with open("notes.txt", encoding="utf-8") as file:
    text = file.read()

file.closed  # True:离开 with 后文件已关闭

# 也能在同一个 with 中管理多个资源
with open("notes.txt", encoding="utf-8") as source, open("copy.txt", "w", encoding="utf-8") as target:
    target.write(source.read())  # 退出时两个文件都会关闭

with 不创建新的变量作用域:块外仍能访问 file,但不能再从已关闭的文件读取。异步资源(如异步数据库连接)通常使用 async with。

异步:asyncio

python 复制代码
import asyncio

async def fetch_user(uid: int) -> dict[str, int]:
    await asyncio.sleep(1)  # 模拟异步 I/O,不阻塞事件循环
    return {"id": uid}

async def main() -> None:
    first, second = await asyncio.gather(fetch_user(1), fetch_user(2))
    print(first, second)

asyncio.run(main())  # 程序入口启动事件循环

调用 fetch_user(1) 只会得到协程对象;需要 await(或创建任务)才会执行。async def 内不要直接调用 time.sleep() 等阻塞操作;在 FastAPI 中,同步路由可写 def,异步路由用 async def 配合异步 I/O。

常用标准库

python 复制代码
from pathlib import Path

path = Path("app") / "config.json"
path.suffix                         # '.json'
# path.read_text(encoding="utf-8")  # 文件存在时读取文本

import json
json.dumps({"name": "键盘"}, ensure_ascii=False)  # JSON 字符串,保留中文
json.loads('{"name": "键盘"}')                   # 解析 JSON

from datetime import datetime, timezone
now = datetime.now(timezone.utc)  # 需要明确时区时,使用带时区的时间

易错点速查

python 复制代码
value = 0
value or 10                    # 10:or 会跳过 0、""、[]、None 等假值
value if value is not None else 10  # 0:只想排除 None 时用这个

rows = [[]] * 3               # 错:三个位置引用同一个列表
rows = [[] for _ in range(3)] # 对:三个独立列表

赋值与作用域:nonlocal / global

Python 赋值不用 let、var 等声明前缀。函数内给名字赋值,默认会把它视为该函数的局部变量;读外层变量不用声明,想重新赋值外层变量才需要说明作用域:

python 复制代码
count = 0  # 模块级变量

def increase() -> None:
    global count       # 重新赋值模块级变量
    count += 1


def make_counter():
    total = 0

    def next_count() -> int:
        nonlocal total  # 重新赋值外层函数的变量(不是模块级变量)
        total += 1
        return total

    return next_count

next_count = make_counter()
next_count()           # 1
next_count()           # 2

如果去掉 nonlocal total,total += 1 会把 total 当作局部变量,却在赋值前先读取它,抛出 UnboundLocalError。global 指模块作用域;nonlocal 指最近的、已存在同名变量的外层函数 作用域。这里只是重新绑定名字需要声明;如 items.append(x) 这种修改对象本身,不需要声明。

match:模式匹配不是普通比较

match(Python 3.10+)先计算表达式,再从上到下尝试 case,执行第一个匹配成功且通过 if 守卫的分支。case 后写的是模式,可以同时检查结构并提取数据:

python 复制代码
def describe(value: object) -> str:
    match value:
        case None:                                  # 字面量
            return "空值"
        case 0 | 1:                                 # 匹配其中之一
            return "零或一"
        case [first, *rest]:                        # 匹配序列并解包;tuple 也可以
            return f"首项 {first},剩余 {rest}"
        case {"name": str(name), "age": int(age)} if age >= 18:
            return f"成年用户 {name}"               # dict 可有额外的键;if 是守卫
        case _:                                     # 其他情况;一般放最后
            return "其他"
模式 含义
case "start": / case None: 匹配字面量;None、True、False 也可直接写
`case "start" "stop":`
case [first, *rest]: 匹配序列并绑定元素;str 不算这种序列模式
case {"id": uid}: 匹配包含 "id" 的映射,并把对应值绑定给 uid
case str(text): 要求对象是字符串,并绑定到 text
case pattern if condition: 模式成功后再检查条件;不满足就尝试下一个 case
case _: 通配符,不绑定变量;通常作最后一个分支

**最容易误解:case name: 不是拿现有变量 name 来比较,而是把待匹配的值绑定到 name。**它像赋值一样无需声明前缀,绑定发生在当前作用域;若放在后续分支前,还会使后续分支不可达(语法错误)。

python 复制代码
expected = "start"
match "stop":
    case expected:             # 捕获模式:总能匹配,覆盖原来的 expected
        print(expected)        # 'stop'

expected = "start"
match "stop":
    case actual if actual == expected:  # 想和变量比较:用守卫
        print("匹配")
    case _:
        print("不匹配")              # 输出:不匹配

固定常量可用带点的名称做值模式,而不是裸名称:

python 复制代码
class Command:
    START = "start"

match "start":
    case Command.START:  # 与 Command.START 的值比较,不会绑定变量
        print("启动")
    case _:
        print("其他")

nonlocal / global 解决的是函数内重新赋值外层变量的问题;match 裸名称捕获是模式语法规则 ,不能用它们把 case name 变成"与变量比较"。

相关推荐
奕鼎竜瑆1 小时前
[新手小白也能学会] 01-PyTorch框架使用(上)
人工智能·pytorch·python
海天一色y1 小时前
图像分割全解析:从经典算法到深度学习的原理与实战(Python + MATLAB)
python·深度学习·算法
三点水-here1 小时前
从 Miniconda 迁移到 Miniforge3 全记录:安装、配置、环境迁移与排错实录
python·conda
夜雪一千2 小时前
Python URL解码详解:单层、双重URL解码实战与踩坑指南
linux·服务器·python
VIP_CQCRE2 小时前
用 Ace Data Cloud 一站式接入 AI 视频生成:HappyHorse Videos API 实战指南
python·aigc·api·ai视频·acedatacloud
kali-Myon2 小时前
定向 FGSM 攻击:让神经网络《指猫为狗》
图像处理·python·神经网络·安全·机器学习·fgsm
老歌老听老掉牙2 小时前
旅行商问题:从数学模型到 Python 实战
开发语言·python
CC数分2 小时前
数据可视化入门:用Python把一堆数字变成一张图
开发语言·python·信息可视化·数据分析
打工仔折腾 AI2 小时前
Prometheus接入Pushgateway实战:二进制与Docker部署、指标推送与远程写入
后端·python·docker·容器·性能优化·prometheus·ai agent 实战