如果你刚开始学编程,可能会发现 Python 和 C++ 里都有“类”(class),但用起来差别挺大。比如:

  • C++ 的类如果不创建实例,就像一张“设计图”,几乎不能直接用里面的功能;
  • Python 的类就算不创建实例,也能直接调用里面的方法,而且方法还分好几种。

这背后其实是两种语言对“类”的理解不同,甚至连方法的设计都因此大不一样。今天就用大白话聊聊这些区别和原因。

一、先看最直观的区别:类什么时候“活”过来?

C++ 的类:“设计图”要变成“实物”才能用

在 C++ 里,当你写下 class 定义时,它更像一张“设计图”——告诉编译器“这个类长什么样”,但这张图本身不会占用计算机的运行内存。

比如你定义一个 Person 类:

class Person {
public:
    void say_hello() {  // 普通方法(非静态)
        cout << "你好" << endl;
    }
    static void static_func() {  // 静态方法
        cout << "我是静态方法" << endl;
    }
};

这时候,Person 类只是编译器认识的“图纸”:

  • 普通方法(如 say_hello)必须先“造个实物”(创建实例)才能用:Person p; p.say_hello();
  • 只有静态方法(加了 static)能直接用类调用:Person::static_func();,但静态方法不能访问实例相关的内容。

为什么?因为 C++ 觉得“设计图”(类)本身不能干活,只有按图纸造出来的“实物”(实例)才能干活,静态方法只是附着在图纸上的“小工具”。

Python 的类:定义完就是“活的”,方法还分三种

在 Python 里,情况完全不同。当你写下 class 定义时,解释器会立刻把这个类变成一个“活的对象”(叫“类对象”),直接占用内存。更特别的是,Python 给类设计了三种方法,对应不同的使用场景:

class Person:
    # 1. 实例方法:依赖实例,第一个参数是 self(代表实例)
    def instance_method(self):
        print(f"我是实例 {self} 的方法")

    # 2. 类方法:依赖类本身,第一个参数是 cls(代表类),用 @classmethod 标记
    @classmethod
    def class_method(cls):
        print(f"我是类 {cls} 的方法")

    # 3. 静态方法:不依赖实例也不依赖类,用 @staticmethod 标记
    @staticmethod
    def static_method():
        print("我是独立的静态方法")

不用创建实例,就能直接调用后两种方法:

Person.class_method()  # 直接用类调用类方法
Person.static_method()  # 直接用类调用静态方法

而实例方法需要先创建实例:

p = Person()
p.instance_method()  # 用实例调用实例方法

二、为什么 Python 会有三种方法?因为它对“类”的理解更灵活

Python 设计三种方法,本质是因为它把“类”本身当成了一个“活的对象”,而不仅仅是“实例的设计图”。这三种方法分别对应不同的“依赖关系”:

  • 实例方法(self:专门操作实例的属性(比如实例的名字、年龄),必须绑定实例才能用——就像“每个实物专属的功能”。
  • 类方法(cls:专门操作类的属性(比如统计这个类创建了多少实例),绑定类本身就能用——就像“设计图自带的功能”。
  • 静态方法:和类、实例都没关系,只是逻辑上属于这个类(比如工具类里的计算函数)——就像“贴在设计图上的独立小工具”。

这种设计让 Python 的类更像一个“多功能工具箱”:既可以用它造实例(用实例方法),也可以直接用工具箱本身的功能(类方法、静态方法)。

三、深层原因:两种语言的“性格”决定了差异

1. 静态编译 vs 动态解释:“提前规划”和“边跑边改”

  • C++ 是静态编译型语言
    代码运行前,编译器会把所有代码“翻译”成机器能懂的指令,并且严格检查“谁能调用谁”。类作为“设计图”,编译器知道它的结构,但不会给它分配运行时内存——只有实例化时,才会按图纸在内存中造一个“实物”。因此,非静态方法必须依赖实例(否则找不到操作对象)。

  • Python 是动态解释型语言
    代码边运行边解释,没有提前编译的步骤。当你写下 class 时,解释器会立刻创建一个“类对象”,把类的属性、方法都存进内存。这种“类本身就是对象”的设计,让类可以直接调用自己的方法(类方法、静态方法),甚至能在运行时给类添加新方法。

2. “一切皆对象” vs “严格区分蓝图和实物”

  • Python 的“万物皆对象”哲学
    在 Python 里,数字、字符串、函数、甚至类本身,都是“对象”。类既然是对象,就必须在定义时就存在于内存中,就像你定义一个变量 a = 1 时,a 会立刻占用内存一样。因此,类的方法(尤其是类方法和静态方法)自然可以直接被调用。

  • C++ 的“严格分层”思想
    C++ 把“设计图”(类)和“实物”(实例)分得很清。类只是编译时的“规则”,不占用运行内存;实例才是运行时的“实体”,会占用内存。这种设计让 C++ 运行效率更高,但灵活性较差,所以方法类型也更简单(主要分静态和非静态)。

四、总结:一句话分清两者

  • C++ 的类:是“设计图”,编译时存在,运行时不占内存,大部分方法(非静态)必须通过实例调用,只有少量静态方法能直接用类调用。
  • Python 的类:是“活对象”,定义时就占内存,因此设计了三种方法:依赖实例的实例方法、依赖类的类方法、独立的静态方法,灵活满足不同场景。

这种区别不是“谁好谁坏”,而是设计目标不同:C++ 追求运行速度和严谨性,Python 追求灵活性和易用性。刚开始学不用死记,多写几行代码,自然就体会到啦~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐