2. 类与对象基础:如何定义一个类,如何创建对象,__init__构造方法详解,self参数的本质

好,咱们正式开始聊面向对象编程的核心——类与对象。

说实话,很多初学者学到这里就开始犯迷糊了。什么类啊对象啊,听着像哲学概念。其实没那么玄乎。我当年刚接触Python时,也觉得这东西抽象。直到我在项目中写了一个用户管理系统,才真正体会到:类就是模板,对象就是根据模板造出来的具体实例

2.1 什么是类?什么是对象?

咱们先打个比方。

你想想看,类就像一张建筑设计图。图纸上画好了房子有几室几厅、门窗位置、水电走向。但图纸本身不是房子,你不能住进去。你得照着图纸去施工,盖出来的那一栋栋具体的房子,才是对象

在Python里,class关键字就是用来画这张设计图的。而通过类创建出来的具体实例,就是对象。

一句话总结:

  • :定义了一组属性和行为的模板
  • 对象:根据类创建出来的具体实体,拥有自己的数据

2.2 如何定义一个类

定义类用class关键字,后面跟类名,再加一个冒号。类名一般用大驼峰命名法,比如UserOrderManager

class Dog:
    """这是一个狗的类"""
    pass

嗯,这里要注意:pass表示暂时什么都不做,占个位置。实际开发中,类里面会写属性和方法。

我个人习惯,定义一个类时,先想清楚这个类要封装什么数据、提供什么行为。比如一个Dog类,可能有名字、年龄这些属性,还有叫、跑这些方法。

2.3 如何创建对象

创建对象很简单——调用类名加括号就行。就像调用函数一样。

my_dog = Dog()

这行代码干了三件事:

  1. 在内存中分配一块空间
  2. 调用__init__方法(如果有的话)初始化对象
  3. 返回对象的引用,赋值给my_dog

说白了,my_dog就是一个指向真实对象的“遥控器”。你通过它来操作对象。

2.4 __init__构造方法详解

这个__init__方法,是Python里最常用的魔法方法之一。它的作用是在对象创建后,自动执行初始化操作。

我曾经在项目中踩过一个坑:忘记写__init__,结果每个对象创建后还得手动去设置属性,代码又臭又长。后来老老实实把初始化逻辑都放进__init__里,清爽多了。

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

my_dog = Dog("旺财", 3)
print(my_dog.name)  # 输出:旺财

注意看:__init__的第一个参数永远是self,后面可以跟任意多个参数。创建对象时传入的参数,会直接传递给__init__

小技巧:

__init__不是构造函数,真正的构造函数是__new____init__只是初始化方法。不过日常开发中,我们通常把__init__当作构造函数来用,也没毛病。

2.5 self参数的本质

很多新手看到self就头疼。我刚开始学的时候也纳闷:这玩意儿到底是啥?为什么每个方法都要写它?

其实self就是对象自身的引用。当你调用my_dog.bark()时,Python会自动把my_dog这个对象作为第一个参数传给bark方法。所以self指向的就是调用这个方法的对象本身。

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name}在汪汪叫")

my_dog = Dog("旺财")
my_dog.bark()  # 等价于 Dog.bark(my_dog)

你看,my_dog.bark()Dog.bark(my_dog)效果完全一样。这就是self的本质——它让你在方法内部能访问到当前对象的数据。

避坑指南:

我曾经见过有人把self写成this或者其他名字。虽然语法上允许,但千万别这么干!所有Python程序员都默认用self,你换个名字只会让别人看不懂你的代码。

2.6 完整示例:一个简单的用户类

咱们把上面这些知识点串起来,写一个完整的例子。

class User:
    """用户类"""
    def __init__(self, username, email):
        self.username = username
        self.email = email
        self.is_active = True

    def login(self):
        print(f"用户 {self.username} 登录成功")

    def logout(self):
        print(f"用户 {self.username} 已退出")

# 创建两个用户对象
user1 = User("张三", "zhangsan@example.com")
user2 = User("李四", "lisi@example.com")

user1.login()   # 输出:用户 张三 登录成功
user2.logout()  # 输出:用户 李四 已退出

每个对象都有自己的usernameemailis_active。互不干扰。这就是面向对象的好处——数据和操作绑定在一起,清晰又安全。

2.7 本章知识体系

下面这张图帮你理清类与对象的核心关系:

类 (Class) 设计图 / 模板 定义属性:name, age 定义方法:bark(), run() 使用 class 关键字 实例化 类名() 对象1 (实例) 具体的“东西” name = "旺财" age = 3 通过 self 访问自身数据 对象2 (实例) 另一个具体实例 name = "来福" age = 5 数据独立,互不干扰 __init__ 自动执行 创建对象时自动调用 self = 对象自身引用 方法调用时自动传入

2.8 几个容易混淆的点

概念 说明 常见误区
类 vs 对象 类是模板,对象是实例 把类当对象用(静态方法除外)
属性 vs 变量 属性属于对象,变量属于作用域 在方法里直接定义变量当属性用
self 不是关键字 只是约定俗成的参数名 改成其他名字导致代码难读
__init__ 不是必须的 没有时对象也能创建 以为每个类都必须写__init__

我的建议:

刚开始学的时候,每个类都写上__init__,哪怕里面只写一个pass。养成习惯后,你就不会忘记初始化逻辑了。

好了,类与对象的基础就聊到这儿。记住:类是图纸,对象是房子;__init__是装修队,self是门牌号。把这个比喻刻在脑子里,后面学继承、多态就轻松多了。


公众号:蓝海资料掘金营,微信deep3321