Python 语法详解 —— 面向 C / C++ 开发者

本文档基于 codePython1.py ~ codePython10.py 中的代码示例,逐一解释涉及的 Python 语法。 读者定位:资深 C 语言开发者 + 基础 C++ 开发者,因此会大量与 C/C++ 做对比。


目录

  1. Python 整体哲学:与 C/C++ 的根本差异
  2. 函数定义与参数
  3. 类与面向对象
  4. 魔术方法(__xxx__
  5. 类型注解与 typing 模块
  6. 装饰器
  7. 异步编程:async / await
  8. 异常处理
  9. 模块与包
  10. 高级数据结构与语法糖
  11. 文件与 I/O
  12. 并发编程:threading
  13. 其他实用语法
  14. 总结:Python 与 C/C++ 关键差异速查表

1. Python 整体哲学:与 C/C++ 的根本差异

1.1 动态类型 vs 静态类型

C/C++:

int x = 10;        // 必须声明类型
char* s = "hello"; // 类型固定

Python:

x = 10          # 无需声明类型,运行时推断
x = "hello"     # 同一个变量可以随时改变类型!

代码示例(codePython2.py 第 5-7 行):

def __init__(self, role: str, content: str):
    self.role = role
    self.content = content

这里的 role: str类型注解(Type Hint),但它不是强制约束——它只是给开发者看的”注释”,Python 解释器不会检查类型是否正确。这与 C/C++ 的静态类型系统完全不同。

1.2 缩进代替花括号

C/C++:

if (x > 0) {
    printf("positive");
}

Python:

if x > 0:
    print("positive")    # 缩进(通常是4个空格)表示代码块

代码示例(codePython2.py 第 54-58 行):

def is_visible(self) -> bool:
    return self.status not in ["hidden", "deleted"]

def is_editable(self) -> bool:
    return self.status not in ["locked", "readonly"]

注意:没有花括号,没有 {},完全靠缩进层级来定义函数体、循环体、条件体。

1.3 Python 的”一切皆对象”

在 Python 中,函数、类、模块、甚至类型本身都是对象。这意味着:

  • 函数可以像变量一样传递
  • 类可以动态创建
  • 函数可以有属性

代码示例(codePython2.py 第 430-434 行):

def register_plugin(intent: str):
    def decorator(func):
        plugin_registry[intent] = func
        return func
    return decorator

这里 register_plugin 是一个函数,它返回另一个函数 decorator。这在 C 语言中是不可能的(C 的函数不能嵌套定义并返回),但在 C++ 中可以通过 lambda 或函数对象实现类似效果。


2. 函数定义与参数

2.1 基本函数定义:def

语法:

def 函数名(参数列表):
    """文档字符串(可选)"""
    函数体
    return 返回值  # 可选

与 C/C++ 对比:

特性CC++Python
函数定义int f(int x)int f(int x)def f(x):
返回值类型必须声明必须声明无需声明(可用注解)
参数类型必须声明必须声明无需声明(可用注解)
函数重载不支持支持不支持(同名函数会覆盖)

代码示例(codePython3.py 第 34-63 行):

def simulate_mcp_response(success=True):    # 默认参数
    if success:
        return { ... }                      # 返回字典
    else:
        return { ... }                      # 返回另一个字典

2.2 参数类型注解(Type Hints)

Python 3.5+ 支持类型注解,但仅用于提示,不强制检查

def func(x: int, y: str) -> bool:   # x是int, y是str, 返回bool
    return True

代码示例(codePython2.py 第 5-14 行):

def __init__(
    self,
    role: str,
    content: str,
    name: Optional[str] = None,       # Optional[str] 表示可以是 str 或 None
    status: Optional[str] = None,
    metadata: Optional[Dict] = None,  # Dict 表示字典类型
    id: Optional[str] = None,
    parent_id: Optional[str] = None
):

与 C++ 对比:

  • C++ 的 int x编译时强制检查
  • Python 的 x: int运行时注释,可以用工具(如 mypy)做静态检查,但 Python 解释器本身不检查

2.3 默认参数

def func(x, y=10):    # y 的默认值是 10
    return x + y

代码示例(codePython2.py 第 155 行):

def __init__(self, role, content, parent_id=None, status="active"):

⚠️ 重要陷阱(与 C++ 不同): Python 的默认参数在函数定义时求值,而不是在调用时。如果默认值是可变对象(如列表、字典),会有问题:

def add_item(item, lst=[]):   # ❌ 危险!lst 只初始化一次
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2]  ← 同一个列表!

正确做法:

def add_item(item, lst=None):  # ✅ 安全
    if lst is None:
        lst = []
    lst.append(item)
    return lst

2.4 返回值注解:-> 类型

def func() -> str:      # 返回 str 类型
    return "hello"

def func() -> bool:     # 返回 bool 类型
    return True

def func() -> List[str]:  # 返回字符串列表
    return ["a", "b"]

代码示例(codePython2.py 第 54-55 行):

def is_visible(self) -> bool:
    return self.status not in ["hidden", "deleted"]

2.5 lambda 匿名函数

类似 C++ 的 lambda 表达式,但 Python 的 lambda 只能写单行表达式

lambda 参数: 表达式

代码示例(codePython6.py 第 624 行):

condition_func=lambda ctx: ctx["user_type"] == "admin"

等价于:

def condition_func(ctx):
    return ctx["user_type"] == "admin"

与 C++ lambda 对比:

特性C++ lambdaPython lambda
语法[capture](params){body}lambda params: expr
多行支持不支持
捕获显式捕获列表自动捕获外部变量
用途通用主要用于高阶函数参数

2.6 yield 生成器

yield 类似 C++ 的协程或迭代器,函数可以”暂停”并”恢复”。

代码示例(codePython4.py 第 845-858 行):

def token_stream_generator():
    """模拟一个Token流生成器,每次迭代返回一部分Token。"""
    tokens = ["您好", ",", "欢迎", "使用", ...]
    for token in tokens:
        time.sleep(0.1)  # 模拟生成延迟
        yield token       # ← 暂停并返回值,下次从这继续

调用方式:

for token in token_stream_generator():  # 每次循环调用一次 yield
    print(token)

🎯 个性化理解(来自资深 C 开发者):yield 相当于特殊断点

可以把 yield 想象成一个特殊的断点

  1. next() 调用:执行到 yield 断点处,打印(返回)yield 后面变量的值,然后函数暂停
  2. send(value) 调用:为 yield 后面的变量赋值(即 yield 表达式的结果),然后继续执行
  3. 没有 next()yield 调用:函数会继续执行到下一行 yield函数末尾
def gen():
    x = yield 1      # 第一次 next() 返回 1,暂停
    y = yield x + 10 # send(5) 给 x 赋值为 5,然后返回 15,暂停
    yield y + 100    # send(20) 给 y 赋值为 20,返回 120

g = gen()
print(next(g))       # 1          —— 执行到第一个 yield,返回 1
print(g.send(5))     # 15         —— 给 x 赋 5,执行到第二个 yield,返回 5+10
print(g.send(20))    # 120        —— 给 y 赋 20,执行到第三个 yield,返回 20+100

与 C/C++ 对比:

  • C 语言没有直接等价物
  • C++20 有协程(coroutines),但语法更复杂
  • Python 的 yield 更接近 C++ 的 generator(Boost.Coroutine)

2.7 函数是一等公民

函数可以像变量一样赋值、传递、作为返回值。

代码示例(codePython2.py 第 319 行):

self.subscribers: Dict[str, List[Callable[[StateChangeEvent], None]]] = {}
# 存储的是"函数列表",Callable 表示可调用对象(函数)

代码示例(codePython2.py 第 373-385 行):

def bind(self, callback):
    self.listeners.append(callback)  # 把函数当作值存储

def trigger_event(self):
    for callback in self.listeners:
        callback()  # 调用存储的函数

# 使用:
event_system.bind(prompt.activate)  # 把方法当作参数传递

这在 C 语言中可以通过函数指针实现,在 C++ 中可以通过 std::function 或 lambda 实现。


3. 类与面向对象

3.1 class 定义

语法:

class ClassName:
    """文档字符串"""
    
    class_variable = 0  # 类变量(类似 C++ 的 static 成员)
    
    def __init__(self, ...):  # 构造函数
        self.instance_var = ...  # 实例变量
    
    def method(self, ...):  # 成员方法
        pass

代码示例(codePython2.py 第 4-21 行):

class ContextObject:
    def __init__(self, role: str, content: str, ...):
        self.role = role
        self.content = content
        ...

与 C++ class 的关键区别:

特性C++Python
访问控制public/private/protected没有(全靠约定:_ 表示保护,__ 表示私有)
构造函数ClassName()__init__(self)
析构函数~ClassName()__del__(self)(不常用)
this/self隐式 this 指针显式 self 参数
成员变量在类体中声明__init__ 中通过 self.xxx 动态创建
多继承支持支持(C3线性化算法)
虚函数virtual 关键字所有方法默认都是”虚函数”

3.2 self 参数 —— 与 C++ 的 this 对比

C++:

class Foo {
    int x;
    void setX(int v) { this->x = v; }  // this 是隐式的
};

Python:

class Foo:
    def setX(self, v):   # self 是显式的第一个参数
        self.x = v       # 必须用 self.x 访问成员

为什么 Python 要显式写 self

  • 为了明确区分实例变量和局部变量
  • 在 Python 中,self 只是一个约定名称(不是关键字),你可以叫它 this 或任何名字,但约定都用 self

3.3 __init__ —— 构造函数

__init__ 是 Python 类的构造函数,在对象创建时自动调用。

代码示例(codePython2.py 第 5-14 行):

class ContextObject:
    def __init__(self, role: str, content: str, ...):
        self.role = role
        self.content = content
        ...

创建对象:

obj = ContextObject(role="user", content="hello")
# 不需要 new 关键字!直接调用类名即可

与 C++ 对比:

  • C++:ContextObject* obj = new ContextObject();ContextObject obj;
  • Python:obj = ContextObject() —— 没有 new 关键字

3.4 实例变量 vs 类变量

类变量(类似 C++ 的 static 成员):

class Foo:
    count = 0  # 类变量,所有实例共享
    
    def __init__(self):
        Foo.count += 1

实例变量(每个对象独有):

class Foo:
    def __init__(self, name):
        self.name = name  # 实例变量,通过 self.xxx 创建

代码示例(codePython2.py 第 317 行):

class StateChangeNotifier:
    def __init__(self):
        self.subscribers: Dict[str, List[Callable]] = {}
    # subscribers 是实例变量,每个 StateChangeNotifier 对象都有自己的 subscribers

3.5 @classmethod@staticmethod

@classmethod(类方法):

  • 第一个参数是 cls(类本身),而不是 self(实例)
  • 可以通过类名直接调用,也可以通过实例调用
  • 类似 C++ 的 static 成员函数,但可以访问类变量

@staticmethod(静态方法):

  • 没有 selfcls 参数
  • 就是一个放在类命名空间里的普通函数
  • 类似 C++ 的 static 成员函数,但不能访问类变量

代码示例(codePython2.py 第 171-175 行):

class ContextObject:
    @classmethod
    def from_dict(cls, d):          # cls 是类本身
        obj = cls(d["role"], d["content"], d.get("parent_id"), d.get("status", "active"))
        obj.id = d["id"]
        return obj

调用方式:

# 类方法可以通过类名直接调用
obj = ContextObject.from_dict(some_dict)

3.6 super() —— 调用父类方法

类似 C++ 的 BaseClass::method()

代码示例(codePython6.py 第 432 行):

class MailSorter(MailModuleBase):
    def __init__(self):
        super().__init__("邮件整理")  # 调用父类 MailModuleBase 的 __init__
        self.mail_content = ""

与 C++ 对比:

  • C++:MailModuleBase::MailModuleBase("邮件整理") 或使用初始化列表
  • Python:super().__init__("邮件整理")

3.7 @dataclass —— 数据类

Python 3.7+ 引入,自动生成 __init____repr____eq__ 等方法,类似 C++ 的 POD 结构体。

代码示例(codePython9.py 第 92-101 行):

from dataclasses import dataclass

@dataclass
class CharacterProfile:
    name: str
    background: str
    personality: str
    speaking_style: str
    emotion: str

等价于手动写:

class CharacterProfile:
    def __init__(self, name, background, personality, speaking_style, emotion):
        self.name = name
        self.background = background
        self.personality = personality
        self.speaking_style = speaking_style
        self.emotion = emotion
    
    def __repr__(self):
        return f"CharacterProfile(name={self.name!r}, ...)"
    
    def __eq__(self, other):
        return (self.name, self.background, ...) == (other.name, other.background, ...)

与 C++ struct 对比:

  • C++ struct 只是数据聚合
  • Python @dataclass 自动生成构造函数、字符串表示、比较运算符等

3.8 pydantic.BaseModel —— 带验证的数据模型

类似 @dataclass 但更强大,提供类型验证、序列化/反序列化等功能。

代码示例(codePython7.py 第 92-110 行):

from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime

class MailMeta(BaseModel):
    sender: str = Field(..., description="发件人邮箱地址")
    receiver: str = Field(..., description="收件人邮箱地址")
    subject: str = Field(..., description="邮件主题")
    timestamp: datetime = Field(..., description="邮件接收时间")

特点:

  • Field(...) 中的 ... 表示必填字段
  • Field(None) 表示可选字段
  • 自动进行类型验证(比如 timestamp 必须是 datetime 类型)
  • 提供 .dict().json() 等方法进行序列化

3.9 Enum 枚举

Python 的枚举类似 C++ 的 enum class

代码示例(codePython7.py 第 314-323 行):

from enum import Enum, auto

class TaskState(Enum):
    INIT = auto()        # 自动分配值 1
    PARSED = auto()      # 2
    CLASSIFIED = auto()  # 3
    SUMMARIZED = auto()  # 4
    REPLIED = auto()     # 5
    ARCHIVED = auto()    # 6
    COMPLETED = auto()   # 7

使用方式:

state = TaskState.INIT
if state == TaskState.INIT:
    print("初始化中")
print(state.name)   # "INIT"
print(state.value)  # 1

4. 魔术方法(__xxx__

魔术方法(Magic Methods / Dunder Methods)是 Python 中以双下划线开头和结尾的特殊方法,它们不是被直接调用的,而是由 Python 解释器在特定场景下自动调用。

🎯 个性化理解(来自资深 C 开发者):魔术方法相当于 C++ 的运算符重载

在 C++ 中,你可以重载 operator+operator==operator[] 等运算符,让自定义类型支持内置运算符的语法。Python 的魔术方法本质上是同一件事——通过定义特殊名称的方法,让自定义对象支持 Python 的内置操作。

Python 魔术方法等价 C++ 运算符重载触发场景
__add__(self, other)operator+(const T& other)obj + other
__eq__(self, other)operator==(const T& other)obj == other
__getitem__(self, key)operator[](const Key& key)obj[key]
__call__(self, args)operator()(Args... args)obj(args)
__str__(self)operator<<(ostream&, const T&)print(obj)
__len__(self)无直接等价len(obj)

关键区别:

  • C++ 的运算符重载使用 operator 关键字 + 运算符符号
  • Python 的”运算符重载”使用固定的双下划线方法名
  • Python 的魔术方法覆盖范围更广,还包括对象创建(__init__)、资源管理(__enter__/__exit__)、迭代器(__iter__/__next__)等

4.1 __init__ —— 构造函数

触发时机: 对象创建时自动调用

obj = MyClass(args)  # → 自动调用 __init__(self, args)

代码示例(codePython2.py 第 5-14 行):

def __init__(self, role: str, content: str, ...):
    self.role = role
    self.content = content

4.2 __name__ == "__main__" —— 模块入口检查

这不是魔术方法,而是一个常见的 Python 惯用法。

if __name__ == "__main__":
    # 只有直接运行此文件时才会执行
    main()

作用:

  • 当文件被直接运行时,__name__ 被设为 "__main__"
  • 当文件被 import 导入时,__name__ 被设为模块名(如 "codePython2"
  • 这样可以让一个文件既可以作为脚本运行,也可以作为模块导入

代码示例(codePython2.py 第 264 行):

if __name__ == "__main__":
    engine = ExecutionEngine()
    ...

与 C/C++ 对比:

  • C 语言没有直接等价物
  • 类似用 #ifdef MAIN 宏来控制编译

4.3 __aenter____aexit__ —— 异步上下文管理器

用于 async with 语句,类似 C++ 的 RAII 但用于异步场景。

代码示例(codePython5.py 第 14-18 行):

async with stdio_client(server_params) as (stdio, write):
    async with ClientSession(stdio, write) as session:
        await session.initialize()

async with 的执行流程:

  1. 调用 __aenter__(异步获取资源)
  2. 执行 with 块中的代码
  3. 调用 __aexit__(异步释放资源)

4.4 其他常见魔术方法

魔术方法触发时机类似 C++
__str__str(obj)print(obj)operator<<
__repr__调试输出
__len__len(obj)
__getitem__obj[key]operator[]
__setitem__obj[key] = valueoperator[]
__call__obj(args)operator()
__enter__ / __exit__with obj:RAII
__iter__ / __next__for x in obj:迭代器
__eq__obj == otheroperator==
__lt__obj < otheroperator<
__add__obj + otheroperator+

5. 类型注解与 typing 模块

5.1 基本类型注解

x: int = 10
y: str = "hello"
z: bool = True
def func() -> float:
    return 3.14

5.2 Optional —— 可选类型

Optional[X] 等价于 Union[X, None],表示可以是 X 类型或 None。

代码示例(codePython2.py 第 9 行):

name: Optional[str] = None
# 等价于:name 可以是 str 或 None

5.3 Dict, List —— 泛型容器

代码示例(codePython2.py 第 103 行):

self.nodes: Dict[str, ContextObject] = {}
# 键是 str,值是 ContextObject 的字典

代码示例(codePython2.py 第 108 行):

def trace_chain(self, start_id: str) -> List[ContextObject]:
    # 返回 ContextObject 列表

5.4 Callable —— 可调用类型

代码示例(codePython2.py 第 294 行):

from typing import Callable

self.subscribers: Dict[str, List[Callable[[StateChangeEvent], None]]] = {}
# Callable[[参数类型], 返回值类型]
# 这里表示:接收 StateChangeEvent 参数,返回 None 的函数

5.5 Any —— 任意类型

from typing import Any
x: Any = 10
x = "hello"  # 没问题,Any 表示任意类型

5.6 类型注解只是”注释”

重要: Python 的类型注解不会在运行时检查。以下代码可以正常运行:

def add(x: int, y: int) -> int:
    return x + y

print(add("hello", "world"))  # 输出 "helloworld"!类型注解被忽略

要真正做类型检查,需要使用外部工具如 mypy


6. 装饰器

装饰器(Decorator)是 Python 中修改函数或类行为的一种方式,本质是一个接受函数并返回新函数的高阶函数

6.1 装饰器的本质

# 装饰器语法糖:
@decorator
def func():
    pass

# 等价于:
func = decorator(func)

🎯 个性化理解(来自资深 C 开发者):装饰器 = 模板函数 + 函数指针重命名

假设有一个模板函数(即装饰器函数),其中有一行是函数指针调用——调用传入的入参函数。装饰器会将包含实际入参函数的模板函数重命名为入参函数的名字。

# 模板函数(装饰器)
def decorator(func):          # func 是"入参函数指针"
    def wrapper(*args, **kwargs):  # wrapper 是"模板函数"
        print("调用前")        # 模板的前置逻辑
        result = func(*args, **kwargs)  # ← 函数指针调用!调用传入的函数
        print("调用后")        # 模板的后置逻辑
        return result
    return wrapper             # 返回模板函数

# 使用装饰器
@decorator
def say_hello(name):           # say_hello 是"实际入参函数"
    print(f"你好, {name}")

# 等价于:
# say_hello = decorator(say_hello)
# 即:将包含 say_hello 的模板函数 wrapper 重命名为 say_hello

say_hello("张三")
# 输出:
# 调用前
# 你好, 张三
# 调用后

关键理解:

  • decorator 是模板工厂,接收一个函数指针 func
  • wrapper 是模板函数,内部通过 func(...) 调用传入的函数
  • @decoratorwrapper 重命名为原函数的名字(say_hello
  • 之后调用 say_hello("张三"),实际执行的是 wrapper("张三"),其中包含了模板逻辑 + 原函数调用

6.2 函数装饰器

代码示例(codePython2.py 第 430-434 行):

def register_plugin(intent: str):
    def decorator(func):
        plugin_registry[intent] = func
        return func
    return decorator

使用:

@register_plugin("generate_report")  # 相当于 generate_daily_report = register_plugin("generate_report")(generate_daily_report)
def generate_daily_report(input_text):
    return f"[插件返回] 日报已生成..."

执行流程:

  1. register_plugin("generate_report") 被调用,返回 decorator 函数
  2. @decoratorgenerate_daily_report 函数作为参数传给 decorator
  3. decorator 把函数注册到 plugin_registry 中,然后返回原函数

6.3 FastMCP 工具装饰器

代码示例(codePython5.py 第 119 行):

@app.tool()
async def fetch_data(api_url: str) -> str:
    """模拟从外部API获取数据的工具函数"""
    return f"Data from {api_url}"

这里的 @app.tool()fetch_data 函数注册为 MCP 服务器的一个工具。

6.4 装饰器与 C++ 的对比

特性Python 装饰器C++ 等价物
函数包装@decorator函数包装器 / lambda
注册机制@app.tool()手动注册
AOP 编程装饰器模板 / 宏

7. 异步编程:async / await

Python 的 async/await协程(Coroutine)的实现,类似 C++20 的协程,但语法更简洁。

7.1 基本概念

async def func():      # 定义一个协程函数
    await other_func() # 等待另一个协程完成
    return result

result = await func()  # 在另一个协程中调用

7.2 asyncio.run() —— 事件循环入口

代码示例(codePython5.py 第 24-25 行):

if __name__ == "__main__":
    asyncio.run(main())  # 创建事件循环,运行 main() 协程

与 C++ 对比:

  • C++ 需要手动管理事件循环(如 boost::asio::io_context
  • Python 的 asyncio.run() 自动创建和销毁事件循环

7.3 async with —— 异步上下文管理器

代码示例(codePython5.py 第 14-18 行):

async with stdio_client(server_params) as (stdio, write):
    async with ClientSession(stdio, write) as session:
        await session.initialize()

执行流程:

  1. __aenter__ 异步获取资源
  2. 执行代码块
  3. __aexit__ 异步释放资源

7.4 await —— 等待协程

代码示例(codePython5.py 第 18-21 行):

await session.initialize()                    # 等待初始化完成
response = await session.call_tool(...)       # 等待工具调用结果

await 的作用:

  • 暂停当前协程的执行
  • 让出控制权给事件循环
  • 等待的协程完成后恢复执行

7.5 async def —— 定义协程

代码示例(codePython5.py 第 12 行):

async def main():
    ...

调用协程:

# ❌ 错误:直接调用不会执行协程
main()  # 返回一个 coroutine 对象,不会执行

# ✅ 正确:必须在事件循环中 await
await main()

# ✅ 或者用 asyncio.run()
asyncio.run(main())

7.6 异步与多线程的对比

特性asynciothreading
并发模型单线程协作式多线程抢占式
切换方式await 主动让出操作系统调度
共享数据无需锁(单线程)需要锁
适用场景I/O 密集型CPU 密集型
类似 C++C++20 协程std::thread

8. 异常处理

8.1 try / except / finally

语法:

try:
    # 可能出错的代码
    result = risky_operation()
except SomeError as e:
    # 捕获特定异常
    print(f"出错:{e}")
except Exception as e:
    # 捕获所有异常
    print(f"未知错误:{e}")
else:
    # 没有异常时执行
    print("成功!")
finally:
    # 无论是否异常都执行(类似 C++ 的析构函数)
    cleanup()

代码示例(codePython3.py 第 161-166 行):

try:
    serialized = json.dumps(request_object, ensure_ascii=False, indent=2)
    print("✅ JSON结构合法")
except Exception as e:
    print("❌ JSON格式错误:", e)

8.2 自定义异常

代码示例(codePython3.py 第 171-184 行):

class MCPError(Exception):  # 继承自 Exception
    def __init__(self, code, message, detail=None):
        self.code = code
        self.message = message
        self.detail = detail or "无详细信息"

使用:

raise MCPError(
    code="TOOL_FAIL_002",
    message="工具调用失败:缺少必要参数",
    detail="resume_text 字段未提供"
)

8.3 与 C++ 异常对比

特性C++Python
抛出异常throwraise
捕获异常catchexcept
捕获所有catch(...)except:
清理操作RAII / catch + 清理finally
异常类型任何类型必须是 BaseException 的子类

9. 模块与包

9.1 import 语句

语法:

import module_name                    # 导入整个模块
from module_name import func          # 导入特定函数
from module_name import func as f     # 导入并重命名
from module_name import *             # 导入所有(不推荐)

代码示例(codePython1.py 第 3 行):

from openai import OpenAI  # 从 openai 包中导入 OpenAI 类

与 C/C++ 对比:

  • C:#include <stdio.h> —— 文本包含,编译时
  • Python:import openai —— 运行时加载,模块是对象

9.2 包结构

Python 的包是一个包含 __init__.py 文件的目录。

代码示例(codePython9.py 中的包结构):

actors/
    __init__.py        # 可以是空文件,标识这是一个包
    character_config.py
    context_manager.py
prompts/
    __init__.py
    character_prompt_templates.py
    emotion_map.py
    story_templates.py

导入方式:

from actors.character_config import CHARACTER_CONFIGS
from prompts.emotion_map import emotion_tone_hint

10. 高级数据结构与语法糖

10.1 列表推导式(List Comprehension)

类似数学中的集合构造:{ x² | x ∈ [1,10], x 是偶数 }

语法:

[表达式 for 变量 in 可迭代对象 if 条件]

代码示例(codePython2.py 第 141 行):

return [p for p in self.prompts if model_capability in p.status]

等价于:

result = []
for p in self.prompts:
    if model_capability in p.status:
        result.append(p)
return result

代码示例(codePython2.py 第 144 行):

return [p.to_dict() for p in self.prompts]

与 C++ 对比:

  • C++ 需要手动写循环
  • C++20 有 ranges 库可以实现类似效果,但语法更复杂

10.2 字典推导式

{k: v for k, v in iterable if condition}

代码示例(codePython7.py 第 384 行):

self._kv_cache = {item["step"]: item["data"] for item in self._chain}

10.3 字典的 get / setdefault 方法

dict.get(key, default) —— 安全获取值,不存在时返回默认值:

代码示例(codePython2.py 第 250 行):

return context_cache.get(session_id, None)
# 等价于:
# if session_id in context_cache:
#     return context_cache[session_id]
# else:
#     return None

dict.setdefault(key, default) —— 获取值,不存在时设置默认值并返回:

代码示例(codePython2.py 第 320 行):

self.subscribers.setdefault(event_type, []).append(handler)
# 等价于:
# if event_type not in self.subscribers:
#     self.subscribers[event_type] = []
# self.subscribers[event_type].append(handler)

10.4 enumerate —— 带索引的遍历

代码示例(codePython8.py 第 262 行):

for idx, row in df.iterrows():
    print(f"第{idx + 1}行:{row_prompt}")

等价于 C++:

for (int i = 0; i < rows.size(); i++) {
    cout << "第" << i+1 << "行:" << rows[i] << endl;
}

10.5 切片操作

语法: list[start:stop:step]

代码示例(codePython9.py 第 136 行):

context = "\n".join(self.history[-3:])  # 取最近3条历史记录

切片操作一览:

lst = [0, 1, 2, 3, 4, 5]
lst[1:4]     # [1, 2, 3]     —— 从索引1到3(不含4)
lst[:3]      # [0, 1, 2]     —— 从开头到索引2(不含3)
lst[::2]     # [0, 2, 4]     —— 步长为2
lst[::-1]    # [5, 4, 3, 2, 1, 0] —— 反转列表

10.6 三元表达式(条件表达式)

语法: 值1 if 条件 else 值2

类似 C 的 条件 ? 值1 : 值2

代码示例(codePython2.py 第 55 行):

return self.status not in ["hidden", "deleted"]

虽然没有直接使用三元表达式,但 Python 的 in / not in 运算符本身就是一个布尔表达式。

代码示例(codePython3.py 第 279 行):

return {"status": "error", "error": "无效Token,认证失败"} if token_input != VALID_TOKEN["token"] else ...

10.7 with 语句 —— 资源管理(类似 RAII)

语法:

with open("file.txt", "r") as f:
    content = f.read()
# 离开 with 块时自动关闭文件

代码示例(codePython4.py 第 439 行):

with Image.open(self.image_path) as img:
    img = img.resize((256, 256))

与 C++ RAII 对比:

  • C++:在析构函数中释放资源
  • Python:with 语句调用 __enter____exit__ 魔术方法

10.8 join() —— 字符串拼接

语法: "分隔符".join(字符串列表)

代码示例(codePython9.py 第 136 行):

context = "\n".join(self.history[-3:])  # 用换行符拼接历史记录

等价于 C++:

std::string result;
for (const auto& s : history) {
    result += s + "\n";
}

10.9 f-string —— 格式化字符串

Python 3.6+ 引入,类似 C 的 printf 但更强大。

语法: f"文本 {变量} 文本"

代码示例(codePython2.py 第 241 行):

print(f"[ERROR] 无效ID: {ctx_id}")
print(f"[WAIT] Prompt '{ctx.content[:20]}...' 被中断,等待恢复")

与 C/C++ 对比:

  • C:printf("x = %d", x);
  • C++:std::cout << "x = " << x;
  • Python:print(f"x = {x}")

10.10 in / not in —— 成员检查

语法: 元素 in 容器

代码示例(codePython2.py 第 55 行):

return self.status not in ["hidden", "deleted"]

代码示例(codePython9.py 第 309 行):

if any(word in msg for word in trigger_words):
    return True

10.11 any() / all() —— 存在性/全称检查

any(iterable) 只要有一个元素为 True,就返回 True all(iterable) 所有元素都为 True,才返回 True

代码示例(codePython9.py 第 309 行):

if any(word in msg for word in trigger_words):
    # 如果 msg 中包含任意一个 trigger_words 中的词
    return True

代码示例(codePython9.py 第 319 行):

return all(any(word in msg for word in key_words) for msg in messages)
# 对于 messages 中的每一条 msg,都包含至少一个 key_words 中的词

10.12 sorted() —— 排序

代码示例(codePython6.py 第 641-643 行):

active_blocks = sorted(
    [b for b in blocks if b.condition_func(context)],
    key=lambda b: b.priority  # 按优先级排序
)

与 C++ 对比:

  • C++:std::sort(vec.begin(), vec.end(), cmp);
  • Python:sorted(list, key=func) —— 更简洁

10.13 max() / min() —— 最大值/最小值

代码示例(codePython9.py 第 433 行):

new_emotion = max(emotion_score.items(), key=lambda x: x[1])[0]
# 在 emotion_score 字典中,找出值最大的键

11. 文件与 I/O

11.1 open() —— 打开文件

语法: open(path, mode, encoding)

代码示例(codePython4.py 第 702 行):

with open(file_path, "r", encoding="utf-8") as file:
    raw_text = file.read()

常用模式:

模式含义类似 C
"r"只读"r"
"w"写入(覆盖)"w"
"a"追加"a"
"rb"二进制读"rb"
"wb"二进制写"wb"

11.2 json 模块 —— JSON 序列化

json.dumps(obj) 将 Python 对象转为 JSON 字符串 json.loads(str) 将 JSON 字符串转为 Python 对象

代码示例(codePython2.py 第 195 行):

data = [p.to_dict() for p in chain]
return json.dumps(data, indent=2, ensure_ascii=False)

代码示例(codePython2.py 第 199 行):

data = json.loads(snapshot_json)

Python 与 JSON 类型映射:

PythonJSON
dict{}
list[]
str""
int / float数字
True / Falsetrue / false
Nonenull

11.3 os.path / os.makedirs —— 路径操作

代码示例(codePython7.py 第 397 行):

os.makedirs(LOG_DIR, exist_ok=True)  # 创建目录,如果已存在也不报错

代码示例(codePython8.py 第 251 行):

if not os.path.exists(data.path):
    return f"[错误] 文件不存在:{data.path}"

11.4 base64 编码

代码示例(codePython4.py 第 453 行):

encoded_str = base64.b64encode(image_data).decode("utf-8")

12. 并发编程:threading

12.1 threading.Thread —— 多线程

代码示例(codePython6.py 第 699-728 行):

import threading
import time

class TaskSession:
    def __init__(self, task_id):
        self.task_id = task_id
        self.state = "初始化"
        self.context = []

    def update(self, user_input):
        self.context.append(user_input)
        self.state = f"处理中: {user_input}"

    def finalize(self):
        self.state = "已完成"

def run_task(task_id, messages):
    session = TaskSession(task_id)
    for msg in messages:
        session.update(msg)
        print(f"[{task_id}] 当前状态:{session.state}")
        time.sleep(0.5)
    session.finalize()
    print(f"[{task_id}] 最终状态:{session.state}")

# 启动两个并发任务线程
t1 = threading.Thread(target=run_task, args=("任务A", ["查询天气", "查看气温"]))
t2 = threading.Thread(target=run_task, args=("任务B", ["读取邮件", "发送报告"]))
t1.start()
t2.start()
t1.join()  # 等待 t1 完成
t2.join()  # 等待 t2 完成

与 C++ pthread 对比:

特性C++ (pthread/std::thread)Python threading
创建线程std::thread t(func)threading.Thread(target=func)
启动自动启动.start()
等待.join().join()
参数传递构造函数参数args=() 元组
数据竞争需要 mutex需要 Lock(GIL 提供部分保护)

12.2 Python 的 GIL(全局解释器锁)

重要概念: Python 的多线程不能真正并行执行 CPU 密集型任务,因为 GIL 确保同一时刻只有一个线程执行 Python 字节码。

  • I/O 密集型任务:多线程有效(如网络请求、文件读写)
  • CPU 密集型任务:多线程无效,应使用 multiprocessing 模块

13. 其他实用语法

13.1 isinstance() —— 类型检查

代码示例(codePython4.py 第 65 行):

if last_prompt["role"] == "user":

虽然没有直接使用 isinstance,但类似的类型检查在代码中很常见。

isinstance(obj, ClassName)  # 检查 obj 是否是 ClassName 的实例
isinstance(obj, (A, B, C)) # 检查 obj 是否是 A、B、C 中任意一个的实例

13.2 copy.deepcopy() —— 深拷贝

代码示例(codePython7.py 第 366 行):

from copy import deepcopy

self._chain.append({"step": step_name, "data": deepcopy(data)})

浅拷贝 vs 深拷贝:

  • 浅拷贝:只复制引用,不复制对象本身
  • 深拷贝:递归复制所有对象

13.3 uuid.uuid4() —— 生成唯一ID

代码示例(codePython2.py 第 156 行):

import uuid
self.id = str(uuid.uuid4())  # 生成类似 "550e8400-e29b-41d4-a716-446655440000" 的字符串

13.4 time.sleep() —— 延时

代码示例(codePython2.py 第 249 行):

time.sleep(delay)  # 暂停 delay 秒

13.5 logging 模块 —— 日志系统

代码示例(codePython5.py 第 39-46 行):

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s | %(levelname)s | %(message)s",
    handlers=[
        logging.FileHandler("mcp_debug.log", encoding="utf-8"),
        logging.StreamHandler()
    ]
)

logging.info("准备调用工具 'add'")
logging.debug("详细调试信息")
logging.warning("警告信息")
logging.error("错误信息")

日志级别(从低到高): DEBUG < INFO < WARNING < ERROR < CRITICAL

13.6 hasattr() / getattr() —— 属性操作

hasattr(obj, "attr_name")  # 检查对象是否有某个属性
getattr(obj, "attr_name")  # 获取属性值
getattr(obj, "attr_name", default)  # 获取属性值,不存在时返回默认值

13.7 str() / repr() —— 字符串表示

str(obj)   # 面向用户的字符串表示(类似 C++ 的 operator<<)
repr(obj)  # 面向开发者的字符串表示(调试用)

13.8 len() —— 获取长度

len(list)    # 列表长度
len(str)     # 字符串长度
len(dict)    # 字典键值对数量

13.9 range() —— 生成数字序列

range(5)       # 0, 1, 2, 3, 4
range(1, 5)    # 1, 2, 3, 4
range(0, 10, 2) # 0, 2, 4, 6, 8

13.10 type() —— 获取类型

type(10)       # <class 'int'>
type("hello")  # <class 'str'>
type(obj)      # <class '__main__.ClassName'>

13.11 dir() —— 列出对象属性和方法

dir(obj)  # 返回对象所有属性和方法的列表

13.12 zip() —— 并行遍历

names = ["张三", "李四", "王五"]
ages = [28, 32, 26]
for name, age in zip(names, ages):
    print(f"{name} 今年 {age} 岁")

13.13 map() / filter() —— 函数式编程

map(func, iterable)     # 对每个元素应用函数
filter(func, iterable)  # 过滤出满足条件的元素

13.14 集合操作

s = {1, 2, 3}           # 集合定义
s.add(4)                # 添加元素
s.remove(2)             # 删除元素
{1, 2} | {2, 3}         # 并集:{1, 2, 3}
{1, 2} & {2, 3}         # 交集:{2}
{1, 2} - {2, 3}         # 差集:{1}

14. 总结:Python 与 C/C++ 关键差异速查表

14.1 语法对照表

功能C/C++Python
注释///* */#
代码块{}缩进(4空格)
行尾;不需要(但可加)
变量声明int x;x = 0(动态类型)
常量const int X = 10;X = 10(约定大写,无强制)
布尔值true / falseTrue / False
空值NULL / nullptrNone
逻辑运算符&& `
自增/自减++i i--不支持(用 i += 1
switch-caseswitch(x) { case 1: ... }不支持(用 if-elif-else
do-whiledo { ... } while(cond);不支持
三目运算符cond ? a : ba if cond else b
数组int arr[10];arr = [0] * 10(列表)
字符串char* / std::stringstr = "hello"
结构体struct@dataclass 或普通类
联合体union不支持
指针int* p = &x;没有指针(一切引用)
引用int& r = x;所有变量都是引用语义
new/deletenew / delete直接创建,自动垃圾回收
头文件#includeimport
宏定义#define常量或函数
模板template<T>动态类型(无需模板)
命名空间namespace模块(文件名即命名空间)
异常try/catch/throwtry/except/raise
文件操作fopen/fcloseopen() + with 语句

14.2 Python 特有、C/C++ 没有的概念

概念说明
动态类型变量类型在运行时确定,可随时改变
垃圾回收自动内存管理(引用计数 + 分代回收)
列表推导式[x**2 for x in range(10)]
装饰器@decorator 修改函数行为
生成器yield 暂停/恢复函数
协程async/await 异步编程
魔术方法__init__, __str__ 等双下划线方法
一切皆对象函数、类、模块都是对象
GIL全局解释器锁,限制多线程并行
with 语句资源管理(类似 RAII)
f-stringf"Hello {name}" 字符串插值

14.3 C/C++ 特有、Python 没有的概念

概念说明
指针Python 没有指针操作
手动内存管理Python 自动垃圾回收
编译时类型检查Python 运行时类型检查
宏定义Python 没有预处理器
头文件Python 用 import 替代
switch-case用 if-elif-else 替代
do-while用 while True + break 替代
运算符重载Python 通过魔术方法实现
模板/泛型Python 动态类型无需模板
const 正确性Python 没有 const 关键字
位域Python 不支持
unionPython 不支持

最后建议: 作为 C/C++ 开发者学习 Python,最大的挑战不是语法本身,而是思维方式的转变

  1. 从”编译器帮我检查类型”到”运行时自己负责”
  2. 从”手动管理内存”到”信任垃圾回收器”
  3. 从”编译-链接-运行”到”解释执行”
  4. 从”花括号组织代码”到”缩进组织代码”

但好消息是:Python 的语法比 C++ 简单得多,学习曲线更平缓。你已有的编程思维(变量、循环、函数、类、异常处理等)全部可以迁移到 Python 中。