2.1 语法骨架与变量
前置:1.1 · 约 25 分钟 · 官方对应:Python 速览、数据模型:对象、值与类型
目标
- 读懂缩进块、注释、文档字符串、续行。
- 理解“变量是绑定到对象的名字”,类型属于对象而不属于变量。
- 区分
==(值相等)与is(同一对象),知道is只该用于None等单例。
核心概念
语句、缩进与注释
- 一行一条语句,不需要分号。以冒号
:结尾的行(if、for、def、class等)开启一个代码块,块内统一缩进(约定 4 个空格)。 #到行尾是注释。三引号字符串放在模块、函数、类的第一行时称为文档字符串(docstring),可用help()或__doc__查看。- 括号
()、[]、{}内可以自由换行(隐式续行),这是长表达式换行的推荐方式。
Python · 可运行
python
def area(width, height):
"""返回矩形面积。""" # 文档字符串
return width * height # 行尾注释
total = (
area(2, 3)
+ area(4, 5)
)
print(total)
print(area.__doc__)变量:名字绑定到对象
赋值语句 x = 值 的含义是:把名字 x 绑定到右侧求值得到的对象。变量没有类型,对象有类型;同一个名字可以先后绑定不同类型的对象(动态类型)。但对象之间不会隐式转换(强类型)。
Python · 可运行
python
x = 42
print(type(x)) # <class 'int'>
x = "四十二"
print(type(x)) # <class 'str'>
a, b = 1, 2 # 多重赋值(本质是元组解包)
a, b = b, a # 交换
print(a, b)
count = 0
count += 1 # 增强赋值,等价 count = count + 1
print(count)两个名字可以绑定同一个对象。对可变对象(如列表)通过任一名字修改,另一个名字也会“看到”变化:
Python · 可运行
python
a = [1, 2]
b = a # 不是复制,b 与 a 指向同一个列表
b.append(3)
print(a) # [1, 2, 3]
print(a is b) # True:同一个对象
c = list(a) # 显式复制,得到新对象
print(c == a, c is a) # True False== 与 is
| 运算 | 比较什么 | 用途 |
|---|---|---|
a == b | 值是否相等(调用 __eq__) | 绝大多数比较 |
a is b | 是否同一个对象(身份,id()) | 只用于单例与哨兵:x is None |
Python · 可运行
python
x = None
print(x is None) # 推荐写法
print(x == None) # 能工作,但不推荐(PEP 8)
print([1] == [1], [1] is [1]) # True False命名约定(PEP 8)
| 写法 | 含义 | 例子 |
|---|---|---|
snake_case | 变量、函数、模块 | max_turns、get_weather |
UPPER_CASE | 常量(约定,语言不强制) | MAX_TURNS、PROVIDERS |
PascalCase | 类 | Anthropic、ToolResult |
_name | 内部使用(约定) | _cache |
__name__ | 特殊名字(dunder),由语言定义 | __init__、__name__ |
易错点
- 使用未赋值的名字:
NameError。3.10 起报错会提示“Did you mean …”;3.12 起对未导入的标准库模块还会提示“Did you forget to import …”(核对日期 2026-10-06)。 - 以为
b = a是复制:对列表、字典等可变对象,它只是多了一个名字。 - 用
is比较字符串或数字:结果取决于实现细节(小整数缓存、字符串驻留),不可靠;比较值用==。 - 缩进不一致:同一块内缩进必须一致,否则
IndentationError。
Python · 可运行演示报错
python
message = "hello"
print(mesage) # 拼写错误对照
| 概念 | Python | JS | Java |
|---|---|---|---|
| 声明变量 | x = 1(无关键字) | let x = 1 / const | int x = 1; / var x = 1; |
| 常量 | MAX = 5(仅约定) | const MAX = 5 | static final int MAX = 5; |
| 类型 | 动态 + 强类型 | 动态 + 弱类型("1" + 1 === "11") | 静态 + 强类型 |
| 同一对象 | a is b | a === b(对象) | a == b(引用) |
| 值相等 | a == b | 需自己比较/深比较 | a.equals(b) |
读代码
minimal_agent.py 中:
python
MAX_TURNS = 5 # 最多与模型往返几轮,防止无限循环
provider = os.getenv("LLM_PROVIDER") or "deepseek"
config = PROVIDERS[provider]MAX_TURNS、PROVIDERS、TOOL_FUNCTIONS全大写:表示“模块级常量,不要修改”。config = PROVIDERS[provider]不复制字典:config与PROVIDERS["deepseek"]是同一个 dict 对象。代码只读不写,所以没有问题;若修改config会影响PROVIDERS。
练习
练习 1:交换与增强赋值
给定 x = 3、y = 10。用一条多重赋值语句交换两者,然后让 x 增加 5(用增强赋值)。最终应满足 x == 15、y == 3。
练习
x = 3
y = 10
# 在下面写代码
快捷键:⌘/Ctrl + Enter 提交检查
练习 2:别名与复制
original 是一个列表。让 alias 成为它的别名(同一对象),让 copy 成为它的副本(值相等、不同对象),然后只通过 alias 追加元素 4。
练习
original = [1, 2, 3]
alias = None
copy = None
快捷键:⌘/Ctrl + Enter 提交检查
小结
- 冒号开块、缩进定界;括号内可自由换行。
- 赋值是“名字 → 对象”的绑定;类型属于对象。
==比值,is比身份,is只用于None等单例。- 全大写名字是约定的常量。