在 Python 中,类(Class) 是面向对象编程的核心,它是一种 “模板” 或 “蓝图”,用于描述具有相同属性(数据)和方法(行为)的对象的集合。通过类,我们可以将数据和操作数据的函数封装在一起一起,实现代码的模块化和复用。

一、类的基本概念

  • 类(Class):是抽象的 “模板”,定义了对象的属性(如 “名字”“年龄”)和方法(如 “说话”“走路”)。例如:“人类” 就是一个类,它包含属性(姓名、身高)和方法(吃饭、睡觉)。
  • 对象(Object):是类的具体实例(根据模板创建的具体 “东西”)。例如:“张三” 是 “人类” 这个类的一个对象,他有具体的姓名(“张三”)和身高(180cm),能执行吃饭、睡觉等方法。
  • 属性(Attribute):类或对象的数据(变量),描述对象的特征。
  • 方法(Method):类中定义的函数,描述对象的行为,只能通过对象或类调用。

二、类的定义

1. 基本语法:self代指当前对象实例,cls代表当前类
class 类名:
    """类的文档字符串(可选,说明类的功能)"""
    # 类属性(所有对象共享的属性)
    类属性名 = 属性值
    
    # 初始化方法(创建对象时自动调用,用于初始化对象的属性)
    def __init__(self, 参数1, 参数2, ...):
        # 实例属性(每个对象独有的属性,用 self. 定义)
        self.实例属性名1 = 参数1
        self.实例属性名2 = 参数2
    
    # 实例方法(操作实例属性的方法,第一个参数必须是 self)
    def 方法名(self, 参数...):
        方法体(可以访问 self. 定义的实例属性)
    
    # 类方法(操作类属性的方法,用 @classmethod 装饰,第一个参数是 cls)
    @classmethod
    def 类方法名(cls, 参数...):
        方法体(可以访问 cls. 定义的类属性)
    
    # 静态方法(与类和对象无关的工具方法,用 @staticmethod 装饰,无默认参数)
    @staticmethod
    def 静态方法名(参数...):
        方法体
2. 关键要素说明
  • 类名:遵循 “大驼峰命名法”(每个单词首字母大写,如 PersonStudentManager),与函数名的蛇形命名法区分。
  • __init__ 方法
    • 称为 “构造方法” 或 “初始化方法”,创建对象时自动执行,用于给对象初始化属性。
    • 第一个参数必须是 self(代表当前对象本身,类似其他语言的 this),后续参数是创建对象时需要传入的属性值。
  • self 的作用
    • 在类的方法中self 指代当前对象,通过 self.属性名 可以访问或修改对象的实例属性,通过 self.方法名() 可以调用对象的其他方法。
    • 调用方法时,self 不需要手动传入,Python 会自动传递当前对象。

三、类的使用(创建对象与调用)

1. 创建对象(实例化)

用 类名(参数) 即可创建对象,参数对应 __init__ 方法中除 self 外的参数。

# 定义一个“人类”类
class Person:
    # 类属性(所有人类共享的属性)
    species = "人类"  # 所有 Person 对象的 species 都是“人类”
    
    # 初始化方法:创建对象时必须传入 name 和 age
    def __init__(self, name, age):
        # 实例属性:每个对象独有的名字和年龄
        self.name = name  # self.name 绑定到传入的 name 参数
        self.age = age    # self.age 绑定到传入的 age 参数
    
    # 实例方法:对象的行为(说话)
    def speak(self):
        # 访问实例属性 self.name 和 self.age
        print(f"我叫{self.name},今年{self.age}岁。")

# 创建对象(实例化):传入 name 和 age 参数
p1 = Person("张三", 20)  # p1 是 Person 类的一个对象
p2 = Person("李四", 30)  # p2 是另一个对象
2. 访问属性
  • 实例属性:通过 对象名.属性名 访问。
  • 类属性:通过 类名.属性名 或 对象名.属性名 访问(推荐用类名,更清晰)。
# 访问实例属性
print(p1.name)  # 输出:张三(p1 的名字)
print(p2.age)   # 输出:30(p2 的年龄)

# 访问类属性
print(Person.species)  # 输出:人类(类名访问)
print(p1.species)      # 输出:人类(对象名也能访问,因为所有对象共享类属性)
3. 调用方法
  • 实例方法:通过 对象名.方法名() 调用(无需传 self)。
  • 类方法:通过 类名.类方法名() 或 对象名.类方法名() 调用。
  • 静态方法:通过 类名.静态方法名() 或 对象名.静态方法名() 调用。
# 调用实例方法
p1.speak()  # 输出:我叫张三,今年20岁。
p2.speak()  # 输出:我叫李四,今年30岁。

四、类的三大特性(封装、继承、多态)

1. 封装(Encapsulation)
  • 定义:将数据(属性)和操作数据的方法捆绑在类中,隐藏内部实现细节,只通过公开的方法与外部交互。
  • 作用:保护数据不被随意修改,提高代码安全性。
  • 实现:通过 “私有属性 / 方法”(命名以 __ 开头)限制外部访问。
class BankAccount:
    def __init__(self, balance=0):
        self.__balance = balance  # 私有属性(外部不能直接访问)
    
    # 公开方法:查询余额(提供外部访问接口)
    def get_balance(self):
        return self.__balance
    
    # 公开方法:存款(控制修改逻辑)
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"存款成功,余额:{self.__balance}")
        else:
            print("存款金额必须为正数")

# 使用
account = BankAccount(100)
print(account.get_balance())  # 输出:100(通过公开方法访问)
account.deposit(50)           # 输出:存款成功,余额:150
# print(account.__balance)    # 报错:私有属性不能直接访问(AttributeError)
2. 继承(Inheritance)
  • 定义:一个类(子类)可以继承另一个类(父类)的属性和方法,子类还可以新增或重写方法。
  • 作用:实现代码复用,减少重复代码。
  • 语法class 子类名(父类名):
# 父类:人类
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def speak(self):
        print(f"我叫{self.name}")

# 子类:学生(继承 Person)
class Student(Person):
    # 新增子类的初始化方法(需要先调用父类的初始化方法)
    def __init__(self, name, age, school):
        # 调用父类的 __init__ 方法,复用属性初始化逻辑
        super().__init__(name, age)
        self.school = school  # 子类新增的属性
    
    # 重写父类的 speak 方法(覆盖父类逻辑)
    def speak(self):
        # 先调用父类的 speak 方法
        super().speak()
        # 新增子类的逻辑
        print(f"我在{self.school}上学")

# 使用子类
s = Student("王五", 18, "北京大学")
s.speak()  # 输出:我叫王五 → 我在北京大学上学(调用重写后的方法)
print(s.age)  # 输出:18(继承父类的属性)
3. 多态(Polymorphism)
  • 定义:不同子类继承父类后,重写父类的方法,使得同一方法调用在不同对象上表现出不同行为。
  • 作用:提高代码灵活性,调用者无需关心对象具体类型,只需调用统一方法。
# 父类:动物
class Animal:
    def make_sound(self):
        pass  # 父类方法为空,由子类重写

# 子类:猫
class Cat(Animal):
    def make_sound(self):
        print("喵喵喵")

# 子类:狗
class Dog(Animal):
    def make_sound(self):
        print("汪汪汪")

# 统一调用函数(不关心具体是猫还是狗)
def animal_sound(animal):
    animal.make_sound()  # 同一方法调用,不同对象表现不同

# 多态体现:传入不同对象,输出不同结果
cat = Cat()
dog = Dog()
animal_sound(cat)  # 输出:喵喵喵
animal_sound(dog)  # 输出:汪汪汪

五、类的其他重要细节

1. 类方法(@classmethod
  • 用于操作类属性,第一个参数是 cls(代表类本身),可以通过 cls.类属性名 访问类属性。
  • 通常用于创建类的实例或操作类级别的数据。
class Car:
    total_cars = 0  # 类属性:记录总车辆数
    
    def __init__(self, brand):
        self.brand = brand
        Car.total_cars += 1  # 每创建一个对象,总车辆数+1
    
    # 类方法:获取总车辆数
    @classmethod
    def get_total_cars(cls):
        return cls.total_cars  # 访问类属性

# 使用
car1 = Car("特斯拉")
car2 = Car("比亚迪")
print(Car.get_total_cars())  # 输出:2(通过类方法获取类属性)
2. 静态方法(@staticmethod
  • 与类和对象无关的工具方法,没有默认参数(不需要 self 或 cls),不能直接访问类属性或实例属性。
  • 通常用于封装与类相关的通用功能(如工具函数)。
class MathUtils:
    # 静态方法:计算两个数的和(与类属性/实例属性无关)
    @staticmethod
    def add(a, b):
        return a + b

# 调用(无需创建对象,直接用类名调用)
print(MathUtils.add(3, 5))  # 输出:8
3. 特殊方法(魔术方法)

Python 中以 __ 开头和结尾的方法是特殊方法,用于实现类的特殊行为(如初始化、打印、运算符重载等)。

  • __init__:初始化对象(最常用)。
  • __str__:定义对象的字符串表示(print 时调用)。
  • __len__:定义对象的长度(len() 函数调用)。
class Book:
    def __init__(self, title, pages):
        self.title = title
        self.pages = pages
    
    # 自定义打印对象时的输出
    def __str__(self):
        return f"《{self.title}》({self.pages}页)"
    
    # 自定义 len() 函数的返回值
    def __len__(self):
        return self.pages

book = Book("Python入门", 300)
print(book)  # 输出:《Python入门》(300页)(调用 __str__)
print(len(book))  # 输出:300(调用 __len__)

六、类的使用步骤总结

  1. 定义类:用 class 关键字,定义属性(类属性 / 实例属性)和方法(实例方法 / 类方法 / 静态方法)。
  2. 创建对象:用 类名(参数) 实例化,自动调用 __init__ 初始化属性。
  3. 操作对象
    • 访问属性:对象名.属性名 或 类名.类属性名
    • 调用方法:对象名.方法名() 或 类名.方法名()
  4. 利用特性:通过封装保护数据,通过继承复用代码,通过多态灵活调用。

七、练习案例

定义一个 “手机” 类 Phone,包含:

  • 实例属性:品牌(brand)、价格(price)。
  • 实例方法:call(number)(输出 “用 [品牌] 手机拨打 [号码]”)。
  • 类属性:system(操作系统,默认 “Android”)。
  • 静态方法:check_network()(输出 “网络正常”)。
class Phone:
    system = "Android"  # 类属性
    
    def __init__(self, brand, price):
        self.brand = brand
        self.price = price
    
    def call(self, number):
        print(f"用{self.brand}手机拨打{number}")
    
    @staticmethod
    def check_network():
        print("网络正常")

# 测试
phone = Phone("华为", 5000)
phone.call("10086")  # 输出:用华为手机拨打10086
print(Phone.system)   # 输出:Android
Phone.check_network() # 输出:网络正常
Logo

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

更多推荐