之前一个月体验了不同的AI编程助手,到了2月份,MinMax-M2.5、GLM-5等新模型相继发布,AI模型的排名榜变化很快。虽然各家总分差异不大,但这种竞争对我们个人或中小团队来说其实是件好事。

我们总说没时间系统学习,但当零碎时间真的来临时,往往又提不起劲。时间就像指缝间的水,越想抓住,流失得越快。去年写了不少Python代码,但大部分功劳要归于AI。所以,我这次想借助Claude Code(下文简称CC),以《Python编程:从入门到实践(第3版)》为蓝本,快速、整体地梳理一遍Python的核心语法。
首先,我在CC里开启了学习模式,不过界面上似乎看不出明显区别😂:

为了防止大语言模型不读教材、仅凭已有知识“自由发挥”,我同时开启了三个CC实例,分别连接MinMax-M2.5、GLM-5和Kimi-2.5三个模型。这样,谁在“偷懒”或“忽悠”我,一对比便知。结果发现,模型们都阅读了教材,但MinMax的总结相对更简练一些。

下面的内容,是我综合三家模型的回复,并结合个人理解整理出来的Python语法核心要点。整个过程也可以在云栈社区与更多开发者交流探讨。
变量和简单的数据类型
变量
变量本质上是值的一个标签,它可以随时被重新赋值,指向新的值。
message = "Hello Python!"
# 定义 message 变量
print(message)
message = 123
print(message)
var_flag = True
varFlag = true # 可以,但不推荐
- 无需声明类型:Python是动态类型语言。
- 命名规则:
- 只能包含字母、数字和下划线。
- 只能以字母或下划线开头。
- 不能包含空格,可用下划线分隔单词(蛇形命名法)。
- 应简短且具有描述性。
- 命名约定:
- 变量名通常小写(
user_name)。
- 全大写一般用于常量(
MAX_CONNECTIONS)。
- 大驼峰命名法用于类名(
ClassName)。
- 可以重复赋值,甚至改变类型。
- 与Java区别:Java默认驼峰,Python默认蛇形。
字符串
- 单引号
'' 和双引号 "" 都可以定义字符串。
- 灵活处理引号:字符串中有单引号就用双引号包裹,反之亦然。
- 丰富的内置方法:
title(), upper(), lower(), strip() 等。
- f-string 是Python 3.6+推荐的字符串格式化方式。
a='an"d3"11' # 单引号中包含双引号
print(a)
ab = "Hello'Time" # 双引号中包含单引号
print(ab)
name = 'Hey, demon.lee'
print(name.title()) # Hey, Demon.Lee 首字母大写
print(name.upper()) # HEY, DEMON.LEE 全大写
print(name.lower()) # hey, demon.lee 全小写
s = " hi,python 123 "
print(f"[{s.lstrip()}]") # [hi,python 123 ] 去掉左边空格
print(f"[{s.rstrip()}]") # [ hi,python 123] 去掉右边空格
print(f"[{s.strip()}]") # [hi,python 123] 去掉两边空格
url="www.google.com/hey/123"
print(url.removeprefix("www.")) # 删除前缀:google.com/hey/123
print(url.removesuffix("www.")) # 删除后缀(没匹配到):www.google.com/hey/123
print(url.removesuffix("/123")) # 删除后缀:www.google.com/hey
msg = "\tHow are you?"
greet = f"{name.title()}{msg}" # 使用 f-string 进行字符串格式化
print(greet) # Hey, Demon.Lee How are you?
数字
主要涉及整数(int)和浮点数(float)。
- 任意两数相除,结果总是浮点数。
- 只要操作数中有浮点数,结果就是浮点数。
- 浮点数计算可能存在微小的舍入误差。
- Python 3.6+ 支持使用下划线提高长整数的可读性。
- 支持同时给多个变量赋值。
** 是乘方运算符,// 是整除运算符。
- 使用
str() 将数字转换为字符串。
c = 10/5
print(c) # 2.0
print(type(c)) # <class 'float'>
c = 1 + 2.2
print(c) # 3.2
c = 0.1 + 0.2
print(c) # 0.30000000000000004
print(f"{c:.1f}") # 0.3 字符串格式化,保留1位小数
print(f"{c:.2f}") # 0.30 字符串格式化,保留2位小数
aa = 12_000_000_000
print(aa) # 12000000000
aa,bb,cc = 11,22,"33"
print(aa,bb,cc) # 11 22 33
print(type(cc)) # <class 'str'>
a = 2 ** 3
b = a / 5
c = a // 6
print(a,b,c) # 8 1.6 1
a = 22
b = 33.21
print("a: "+str(a)) # a: 22
print("b: "+str(b)) # b: 33.21
注释
# 这是单行注释
print("Hello!") # 行内注释
列表
列表简介
列表是Python中最基础、最常用的数据结构之一。
- 使用
[] 定义,元素用 , 分隔,可存储任意类型。
- 有序、可修改,是动态数组,自动扩容。
- 支持负索引(如
-1 表示最后一个元素)。
- 可通过索引直接修改元素。
- 添加元素:
append() 在末尾追加,insert() 在指定位置插入。
- 删除元素:
del 按索引删除,pop() 弹出元素(可指定索引),remove() 按值删除(只删第一个匹配项)。
- 排序:
sort() 原地永久排序,sorted() 临时排序返回新列表,reverse() 反转列表顺序,len() 获取列表长度。
arr = ['字符串', 123, 33.23, True, "test"]
print(arr) # ['字符串', 123, 33.23, True, 'test']
print(arr[1], arr[-1]) # 123 test
arr[0] = "字符"
print(arr) # ['字符', 123, 33.23, True, 'test']
arr = [] # 创建空列表
arr.append("你好") # 追加元素
arr.append(123)
print(arr) # ['你好', 123]
arr.insert(1, True) # 在 index = 1 的位置插入数据,后面的数据自动往后移动
print(arr) # ['你好', True, 123]
arr = ['字符串', 123, 33.23, True, "test"]
del arr[0] # 按索引删除
print(arr) # [123, 33.23, True, 'test']
e = arr.pop() # 弹出最后一个元素
print(e) # test
print(arr) # [123, 33.23, True]
e = arr.pop(1) # 按指定位置弹出元素
print(e) # 33.23
print(arr) # [123, True]
arr.append(123)
arr.remove(123) # 按值删除,但只匹配第一个,无返回值
print(arr) # [True, 123]
arr = [121, 33, 1, 99, 68, 12, 77]
arr1 = sorted(arr) # 临时排序
print(arr1) # [1, 12, 33, 68, 77, 99, 121]
print(arr) # [121, 33, 1, 99, 68, 12, 77]
print(len(arr)) # 7
arr.reverse() # 反转,永久
print(arr) # [77, 12, 68, 99, 1, 33, 121]
arr.sort() # 永久排序(默认升序)
print(arr) # [1, 12, 33, 68, 77, 99, 121]
arr.sort(reverse=True)
print(arr) # [121, 99, 77, 68, 33, 12, 1]
操作列表
- 代码块与缩进:Python用缩进来界定代码块,通常用4个空格,避免混用Tab和空格。
- 遍历列表:
for item in list:。
- 创建数值列表:
range() 函数,常与 list() 结合使用。
- 列表统计:
min(), max(), sum()。
- 列表推导式:一种简洁的创建列表的方式。
- 切片:
list[start:end],创建原列表的子副本(浅拷贝)。list[:] 可复制整个列表。
- 元组:不可变的列表,用
() 定义。单元素元组需加逗号:(item,)。
- 代码风格 (PEP 8):
- 一行不超过80字符。
- 函数、类之间空两行,逻辑块之间空一行。
- 行内注释与代码间隔2个空格。
- 长行可用
() 换行。
- 比较运算符两边加空格。
arr = [121, 33, 1]
for i in arr:
print(i) # 注意缩进
print(f"arr len: {len(arr)}") # 非循环体不需要缩进
# 输出内容如下:
121
33
1
arr len: 3
# 空循环体可以用 pass
# range(stop) - 从 0 开始,stop 不包含在内
# range(start, stop) - stop 不包含在内
# range(start, stop, step) - 带步长
for value in range(1, 3):
print(value)
# 输出内容如下:
1
2
for value in range(2):
print(value)
# 输出内容如下:
0
1
arr = list(range(1, 10, 3)) # 转列表
print(arr) # [1, 4, 7]
arr = [1,3,5]
print(min(arr)) # 1
print(max(arr)) # 5
print(sum(arr)) # 9
even_squares = [x ** 2 for x in range(2,11,2)]
print(even_squares) # [4, 16, 36, 64, 100]
# 切片示例
arr = ['Hey','你好','时间']
arr1 = arr[0:1]
print(arr1) # ['Hey']
arr1.append('world')
print(arr) # ['Hey', '你好', '时间']
print(arr1) # ['Hey', 'world']
print(arr[:2]) # ['Hey', '你好'] 复制:从 0 到 1
print(arr[2:]) # ['时间'] 复制:从 2 到末尾
print(arr[-2:]) # ['你好', '时间'] 复制:从倒数第 2 到末尾
# 元组示例
arr1 = (1, 3, 9)
arr2 = (1) # 这不是元组,而是数字 1
print(type(arr2)) # <class 'int'>
arr3 = (1,) # 这是单元素元组
print(type(arr3)) # <class 'tuple'>
# arr1[0] = 0 # 提示错误:TypeError: 'tuple' object does not support item assignment
arr1 = ('hi', '2026') # 重新赋值是允许的
print(arr1) # ('hi', '2026')
if 语句
Python中没有 switch...case 语句,基本结构如下:
if xx1:
xxx
elif xx2:
xxx
else:
xxx
示例:
age = 12
if age <= 6:
price = 0
elif age < 18:
price = 15
else:
price = 30
print(f"Your admission cost is ${price}.") # Your admission cost is $15.
- 比较与逻辑运算:
- 用
==, != 比较值。
- 用
and, or, not 进行逻辑运算(对应Java的 &&, ||, !)。
- 成员检查:
in 和 not in 可用于检查元素是否存在于列表、字符串、字典等可迭代对象中。
- 链式比较:支持
11 < x < 50 这样的写法。
- 三元表达式:
status = 'adult' if age >= 18 else 'minor'
a = 12
b = 13
c = 'hello'
d = "hello"
print(a==b) # False
print(c==d) # True,没错,字符串也是用 == 比较
f = a == b
if not f:
print("hey...")
arr = ["Jack", "小马", "2026"]
if arr: # 检查列表是否为空
print("arr is not empty.")
if '2026' in arr:
print("here is 2026...")
字典
字典是键值对的无序集合,键必须是唯一的。
- 用
{} 定义,键值对用 : 分隔。
- 基本操作:
- 获取值:
dict[key](键不存在则报错 KeyError)或 dict.get(key)(键不存在返回 None 或指定默认值)。
- 增/改:
dict[key] = value 或 dict.update()。
- 删除:
del dict[key] 或 dict.pop(key)。
- 遍历:
dict.keys()(键),dict.values()(值),dict.items()(键值对)。
- 集合:
set,无序不重复元素的集合。用 set() 或 {}(注意空集合必须用 set())创建。
- 嵌套:支持字典列表、字典中存字典、字典中存列表等复杂数据结构。
d1 = {} # 定义空字典
d2 = {'k1': 11, 2: 'test'}
print(d2['k1']) # 11
print(d2[2]) # test
# print(d2['k2']) # 元素不存在,提示错误:KeyError: 'k2'
print(d2.get('k2')) # 元素不存在,不报错,返回 None
print(d2.get('k2', 'hey')) # 元素不存在,返回默认值 hey
d2['k2'] = 'Hi' # 增加或修改元素
d2.update(k1=110, user="root") # 增加或修改元素
del d2['k2'] # 删除指定 key 的元素
d2.pop('user', None) # 移除指定 key 的元素,如果 key 不存在,就返回 None
print(d2.keys()) # dict_keys(['k1', 2])
print(d2.values()) # dict_values([11, 'test'])
print(d2.items()) # dict_items([('k1', 11), (2, 'test')])
for k, v in d2.items():
print(k, v)
# 集合示例
set1 = set() # 定义空集合
set2 = set(d2.values()) # 使用 d2 的值集合进行初始化
set3 = {'k1', 11, True}
set3.add('Hey')
set3.remove(True)
print(set2) # {'test', 11}
print(set3) # {'k1', 'Hey', 11}
print('c' in set3) # False
# 字典列表
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
print(aliens) # [{'color': 'green', 'points': 5}, {'color': 'yellow', 'points': 10}, {'color': 'red', 'points': 15}]
# 字典中存储字典
users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton',
},
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris',
},
}
# 字典中存储列表
pizza = {
'crust': 'thick', # 值是字符串
'toppings': ['mushrooms', 'extra cheese'], # 值是列表
}
用户输入和 while 循环
- 暂停程序,等待用户输入。
- 返回值类型永远是字符串,需要其他类型需手动转换(如
int(), float())。
msg = input("hello, how old are you?")
age = int(msg)
print(age)
while 循环
- 基础语法与其他语言类似。
- 常配合
in 操作符来安全地删除列表中的特定元素。
- while-else 结构:
else 块在循环正常结束(即条件变为 False)时执行,若由 break 跳出,则不执行 else。
# 删除列表中的元素
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
while 'cat' in pets:
pets.remove("cat")
print(pets) # ['dog', 'dog', 'goldfish', 'rabbit']
# while 判断集合时会自动判断是否为空,不需要额外的 empty 判断
# while xxList: # 如果 xxList 为空,那么判断就是 False
# pass
# while-else 特色结构
numbers = [1, 3, 5, 7, 9]
target = 4
index = 0
while index < len(numbers):
if numbers[index] == target:
print(f"找到 {target} 在索引 {index}")
break
index += 1
else:
print(f"未找到 {target}")
函数
Python中函数是一等公民,可赋值、可传递。
- 定义:使用
def 关键字。无需声明返回类型。使用三引号 """ """ 编写文档字符串。
- 参数传递:
- 默认值参数必须放在末尾。
- 支持位置传参和关键字传参。混合使用时,位置实参在前。
- 任意数量参数:
*args:接收任意数量位置参数,类型为元组。
**kwargs:接收任意数量关键字参数,类型为字典。
**kwargs 必须在参数列表最后。
- 模块导入:支持导入整个模块、导入特定函数、设置别名等。
# 定义
def greet_user(name):
"""显示简单的问候语""" # 函数注释
print(f"Hello, {name}")
return f"hey,{name}"
# 调用
greet_user("Pony") # Hello, Pony
# 默认值
def describe_pet(pet_name, animal_type='dog'): # animal_type 默认 'dog'
print(f"I have a {animal_type} named {pet_name}.")
describe_pet('willie') # 按位置传参
describe_pet(animal_type='hamster', pet_name='harry') # 按关键字传参,顺序不重要
# 任意数量位置参数 (*args)
def make_pizza(*toppings):
print(toppings)
make_pizza('pepperoni', 'mushrooms', 'cheese') # ('pepperoni', 'mushrooms', 'cheese')
# 任意数量关键字参数 (**kwargs)
def build_profile(first, last, **user_info):
user_info['first_name'] = first
user_info['last_name'] = last
return user_info
user = build_profile('albert', 'einstein', location='princeton', field='physics')
print(user) # {'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}
# 模块导入示例
# import pizza # 导入整个模块
# from pizza import make_pizza # 导入特定函数
# import pizza as p # 给模块设别名
# from pizza import make_pizza as mp # 给函数设别名
# from pizza import * # 不推荐:导入模块中所有函数
类
Python使用面向对象编程,支持类与对象。
- 定义与实例:
- 使用
class 定义。
- 构造方法为
__init__(self, ...)。
self 代表实例自身,类似Java的 this,但必须显式写出。
- 创建实例直接调用类名:
instance = ClassName()。
- 可动态添加或修改属性。
- 继承:
- 支持单继承和多继承。
- 调用父类构造:
super().__init__(...)。
- 重写方法直接定义同名方法即可。
- 访问控制(基于约定):
_var:单下划线开头,约定为“私有”,但外部仍可访问。
__var:双下划线开头,会触发名称修饰(Name Mangling),在一定程度上实现隔离。
@property:将方法当作属性访问,实现getter效果。
@属性名.setter:实现setter效果。
__方法名__:魔术方法(如__init__, __str__),在特定时机自动调用。
class Dog:
"""小狗的简单模拟"""
def __init__(self, name, age):
"""初始化属性"""
self.name = name
self.age = age
self.description = '' # 给属性设置默认值
def sit(self):
"""蹲下"""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""打滚"""
print(f"{self.name} rolled over!")
def mock(self, mock_flag):
"""mock"""
self.mock_flag = mock_flag # 动态添加成员属性
print(f"{self.name} mock: {mock_flag}")
dog1 = Dog("Jim", 3)
print(dog1) # <__main__.Dog object at 0x1077052b0>
print(dog1.name) # Jim
dog1.roll_over() # Jim rolled over!
# 继承示例
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
return f"{self.year} {self.make} {self.model}"
class ElectricCar(Car): # 继承 Car
def __init__(self, make, model, year):
super().__init__(make, model, year) # 调用父类构造
self.battery_size = 75
def describe_battery(self):
print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name()) # 2019 tesla model s
my_tesla.describe_battery() # This car has a 75-kWh battery.
# 访问控制示例
class Person:
def __init__(self, name, age):
# 1. 公开属性 - 任何地方都可以访问
self.name = name
# 2. 约定私有 - 单下划线开头
self._age = age
# 3. 名称修饰私有 - 双下划线开头
self.__secret = "hidden"
# getter
@property
def age(self):
return self._age
# setter
@age.setter
def age(self, value):
self._age = value
# 公开方法
def say_hello(self):
print(f"Hello, I'm {self.name}")
# 约定私有方法
def _internal_method(self):
print("Internal use only")
# 名称修饰私有方法
def __private_method(self):
print("Private by name mangling")
jack = Person('Jack', 33)
print(jack.name) # Jack
print(jack._age) # 33 可以访问,但不建议
jack.age = 28 # 通过 `@age.setter` 实现 setter 效果
print(jack.age) # 28 通过 `@property` 实现 getter 效果
# print(jack.__secret) # AttributeError: 'Person' object has no attribute '__secret'
print(jack._Person__secret) # hidden 名称修饰后可访问
文件和异常
文件操作
-
读取:
- 使用
with 语句自动管理资源,无需手动 close()。
- 大文件推荐逐行迭代读取。
-
写入:
-
JSON处理:
json.dumps():Python对象 -> JSON字符串。
json.loads():JSON字符串 -> Python对象。
# 方式1:一次性加载
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
# 方式2:逐行迭代,如果是大文件,推荐此方式
with open('langchain_agent_shell.py') as file_object:
for line in file_object:
print(line.rstrip())
# 方式3:一行行读取
with open('langchain_agent_shell.py') as file_object:
line1 = file_object.readline()
line2 = file_object.readline()
print(line1)
print(line2)
# 方式4:一次性加载所有行到列表
with open('langchain_agent_shell.py') as file_object:
lines = file_object.readlines()
print(f"line num: {len(lines)}")
for line in lines:
print(line.rstrip())
# 写入文件
with open("demo-py.txt", "w") as f:
f.write("你好,Python......\n人生苦短,我用Python。\n")
with open("demo-py.txt", "a", encoding='utf-8') as f:
f.write("测试123......")
# JSON示例
>>> jstr = '{"你好":"hello", "u2":"测试", "u3": null}'
>>> d1 = json.loads(jstr)
>>> type(d1)
<class 'dict'>
>>>
>>> print(d1)
{'你好': 'hello', 'u2': '测试', 'u3': None}
>>>
异常处理
使用 try-except-else-finally 结构。else 块在无异常时执行,finally 块无论是否发生异常都会执行。
try:
file = open('data.txt')
data = file.read()
except FileNotFoundError:
print("File not found")
else:
print("File found")
finally:
print("Cleanup code here")
# 如果 data.txt 不存在,则输出
File not found
Cleanup code here
# 如果 data.txt 存在,则输出
File found
Cleanup code here
常见异常类型:
ZeroDivisionError # 除零
FileNotFoundError # 文件不存在
ValueError # 值错误(如 int("abc"))
TypeError # 类型错误
IndexError # 索引越界
KeyError # 字典键不存在
AttributeError # 属性不存在
NameError # 变量未定义
SyntaxError # 语法错误
ModuleNotFoundError # 模块不存在
ImportError # 导入错误
参考资料
[1] Python 编程(第3版): https://book.douban.com/subject/36365320/