当前位置:首页>python>从C++到Python:一文看懂核心差异,让C++程序员快速上手

从C++到Python:一文看懂核心差异,让C++程序员快速上手

  • 2026-10-11 07:53:19
从C++到Python:一文看懂核心差异,让C++程序员快速上手

有了AI估计大多数时候都不用手写python了,但看懂python还是很重要的。

C++工程师在学 Python 的初期,都会有一种奇怪的割裂感:

  • • “这变量怎么不用声明类型?”
  • • “为什么函数参数能随便传?”
  • • “对象怎么到处都是引用?”
  • • “怎么连头文件都没有?”
  • • “这代码为什么看起来像伪代码?”

本文将通过对比C++和Python的核心差异,帮助你用“对比”的方式学Python,掌握Python的编程思维,快速进入能看懂Python的阶段。

一、类型系统-变量观的重塑:从“内存盒子”到“对象标签”

在 C++ 中,声明变量是开辟内存空间:int a = 10; 是在栈上挖了一个 4 字节的坑,里面填入 10。而在 Python 中,一切皆对象,变量只是一个指针(标签)。

  • • C++:a 是内存地址的别名。
  • • Python:a = 10 是先在堆上创建一个 int 对象,然后让 a 指向它。

C++:

int a = 10;        // 必须声明类型a = "hello";       // 错误!类型不匹配

Python:

a = 10             # 不需要声明类型a = "hello"        # 完全可以,变量只是对象的标签

关键理解: Python变量本质上是对象的引用,类似于C++中的void*指针。Python 的赋值操作更像是 C++ 的智能指针(std::shared_ptr)的拷贝,而不是值的拷贝。Python 不是“没类型”,而是“变量没类型”,类型属于对象。

对于Python:

  • • 对象有类型
  • • 变量只是“引用”

你可以这样理解:

a = 10

更像:

PyObject* a = new IntObject(10);

变量 a 本质上只是一个指针引用。

所以 Python 可以:

a = 10a = "hello"a = [1,2,3]

因为:

变的是引用指向,而不是变量类型。

二、内存管理:手工 vs 自动

C++:

int* p = new int(5);delete p;          // 必须手动释放

Python:

p = 5              # 自动分配内存# 不需要释放,垃圾回收自动处理

关键理解: Python使用引用计数为主、标记清除为辅的垃圾回收机制。当对象引用计数降为0时,自动被删除。

三、核心数据结构对比

Python 的内置容器几乎可以无缝对接 C++ 程序员的思维模型:

操作
C++
Python
数组/列表
vector<int> v; v.push_back(1);v = [1, 2, 3]
键值对
unordered_map<string, int> m; m["a"]=1;m = {"a": 1, "b": 2}
集合
unordered_set<int> s; s.insert(1);s = {1, 2, 3}
元组
C++17 tuple<int,string> t(1,"a");
t = (1, "a")

小技巧: Python 的 List 推导式(List Comprehension)可以看作是极简版的 std::transform。

Python的独特优势:

# 列表推导式 - 让C++程序员羡慕的特性squares = [x**2 for x in range(10) if x % 2 == 0]# 切片操作arr = [1, 2, 3, 4, 5]arr[1:4]      # [2,3,4]arr[::-1]     # 反转:[5,4,3,2,1]
  • • 注意Python 的 list,本质更像 vector<void*>

很多 C++ 工程师第一次看到:

arr = [1, "hello", 3.14]

会感觉不可思议。

因为 C++:

std::vector<int>

必须固定类型。

而 Python list 更像:

std::vector<PyObject*>

里面装的是:

  • • int对象
  • • string对象
  • • float对象

因此:Python 的灵活性,本质来自** “一切皆对象” **。

四、语法形态:从“大括号”到“强制缩进”

C++ 程序员最不习惯的通常是 Python 丢弃了分号和花括号。

作用域: C++ 靠 {} 定义作用域,Python 靠缩进。内存管理: C++ 需要 RAII 机制或手动 delete;Python 依靠 引用计数 (Reference Counting) 和 垃圾回收 (GC)。

五、函数与参数传递

C++ 工程师看到 Python 的对象传递,经常会懵。

C++: 值传递、引用传递、指针传递Python: 一切都是对象引用传递

def modify(lst):    lst.append(4)        # 修改原对象    lst = [1, 2, 3]      # 重新绑定局部变量my_list = [1, 2, 3]modify(my_list)print(my_list)  # 输出 [1, 2, 3, 4],不是 [1,2,3]!

关键理解: 这就像C++中传递指针,但指针本身是值传递。修改指针指向的内容会影响外部,但修改指针本身不会。上面代码片段的理解关键点在于 第二步:

  • • lst = [1, 2, 3] 并不是修改原来的列表内容,而是让局部变量 lst不再指向原来的列表,转而指向一个全新的列表。
  • • 外部的 my_list 对这一切浑然不知,它依然牢牢指着原来的那个已经被追加了 4 的列表。
  • • 函数结束后,局部变量 lst 被销毁,新创建的那个 [1,2,3] 列表因为没有其他引用,也会被垃圾回收。
#用 C++ 类比void modify(void* ptr) {    vector<int>* v = (vector<int>*)ptr;    v->push_back(4);          // 修改原对象    v = new vector<int>{1,2,3}; // 只改变了局部指针的指向,外部 ptr 纹丝不动}int main() {    vector<int>* my_vec = new vector<int>{1,2,3};    modify(my_vec);    // my_vec 指向的仍是原 vector,内容为 {1,2,3,4}}

六、面向对象:显式 vs 隐式

C++:

class Dog {private:    string name;public:    Dog(const string& n) : name(n) {}void bark(){ cout << name << "汪汪" << endl; }};

Python:

class Dog:    def __init__(self, name):        self.name = name      # 动态添加属性    def bark(self):           # self显式传递        print(f"{self.name}汪汪")

主要差异:

  • • Python没有真正的私有成员(约定_name表示保护,__name会名称修饰)
  • • 方法第一个参数必须是self(相当于C++的this)
  • • 支持多重继承(且没有菱形继承问题!)

Python 的“鸭子类型”到底是什么?

经典例子:

class Duck:    def quack(self):        print("duck")class Person:    def quack(self):        print("person")def make_sound(x):    x.quack()

Python 不关心:

  • • 继承关系
  • • 接口定义
  • • 类型声明

只关心:“你有没有 quack()”

这和 C++ 模板其实非常像。

C++ 模板:

template<typename T>void make_sound(T x){    x.quack();}

只要:

x.quack()

能编译就行。

Python 的鸭子类型,本质上更接近“运行时模板”。

七、错误处理:try-catch vs try-except

C++:

try {    throw std::runtime_error("出错了");} catch (const std::exception& e) {    std::cout << e.what() << std::endl;}

Python:

try:    raise RuntimeError("出错了")except RuntimeError as e:    print(e)          # 更简洁finally:    print("不管是否异常都会执行")

Python特色:else子句(没有异常时执行)、finally(清理资源)

八、常见陷阱与最佳实践

陷阱1:默认参数的坑

# 错误示例def add_item(item, lst=[]):   # 默认列表是共享的!    lst.append(item)    return lstprint(add_item(1))  # [1]print(add_item(2))  # [1, 2]  不是 [2]!# 正确做法def add_item(item, lst=None):    if lst is None:        lst = []    lst.append(item)    return lst

陷阱2:循环中修改列表

# 错误for item in lst:    if condition:        lst.remove(item)  # 会导致跳过元素# 正确lst = [item for item in lst if not condition]

陷阱3:变量作用域

x = 10def func():    x += 1      # UnboundLocalError!# 正确:使用global或nonlocaldef func():    global x    x += 1

九、性能考量

特性
C++
Python
循环速度
极快
较慢(尽量避免纯Python循环)
函数调用开销
小
较大
内存占用
可控
较高
优化方向
算法、编译器优化
使用NumPy/C扩展、内置函数

Python性能技巧:

# 慢:纯Python循环total = 0for i in range(1000000):    total += i# 快:使用内置函数total = sum(range(1000000))# 更快:使用NumPy(大数据)import numpy as nptotal = np.sum(np.arange(1000000))

十、快速记忆表

场景
C++
Python
变量声明
int x = 5;x = 5
常量
const int X = 5;
约定X = 5(无真正的常量)
条件判断
if (x > 0) { ... }if x > 0: ...
(注意冒号和缩进)
循环
for (int i=0;i<10;i++)for i in range(10):
nullptr
nullptrNone
逻辑与
&&and
逻辑或
`
取地址
&xid(x)
字符串格式化
printf
 / std::format
f"x={x}"

最新文章

随机文章