类是 Python 面向对象编程的核心概念,它允许你创建自定义的数据结构,封装数据和方法。

类的基本结构

class MyClass:
    """这是一个简单的类示例"""
    
    # 类属性(所有实例共享)
    class_attribute = "我是类属性"
    
    def __init__(self, param1, param2):
        """初始化方法(构造函数)"""
        # 实例属性(每个实例独有)
        self.param1 = param1
        self.param2 = param2
    
    def instance_method(self):
        """实例方法"""
        return f"参数1: {self.param1}, 参数2: {self.param2}"
    
    @classmethod
    def class_method(cls):
        """类方法"""
        return f"类属性值: {cls.class_attribute}"
    
    @staticmethod
    def static_method():
        """静态方法"""
        return "这是一个静态方法"

创建和使用类

# 创建实例
obj = MyClass("值1", "值2")

# 访问属性
print(obj.param1)  # 输出: 值1
print(obj.class_attribute)  # 输出: 我是类属性

# 调用方法
print(obj.instance_method())  # 输出: 参数1: 值1, 参数2: 值2
print(MyClass.class_method())  # 输出: 类属性值: 我是类属性
print(MyClass.static_method())  # 输出: 这是一个静态方法

继承

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

class Dog(Animal):
    def speak(self):
        return f"{self.name} 说: 汪汪!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} 说: 喵喵!"

# 使用继承
dog = Dog("旺财")
cat = Cat("咪咪")
print(dog.speak())  # 输出: 旺财 说: 汪汪!
print(cat.speak())  # 输出: 咪咪 说: 喵喵!

封装

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.__balance = balance  # 私有属性
    
    def deposit(self, amount):
        """存款"""
        if amount > 0:
            self.__balance += amount
            return f"存款成功,当前余额: {self.__balance}"
        return "存款金额必须大于0"
    
    def withdraw(self, amount):
        """取款"""
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return f"取款成功,当前余额: {self.__balance}"
        return "取款金额无效或余额不足"
    
    def get_balance(self):
        """获取余额(封装访问)"""
        return self.__balance

# 使用封装
account = BankAccount("张三", 1000)
print(account.deposit(500))  # 输出: 存款成功,当前余额: 1500
print(account.withdraw(200))  # 输出: 取款成功,当前余额: 1300
print(account.get_balance())  # 输出: 1300

特殊方法(魔术方法)

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        """字符串表示"""
        return f"Vector({self.x}, {self.y})"
    
    def __add__(self, other):
        """加法运算"""
        return Vector(self.x + other.x, self.y + other.y)
    
    def __len__(self):
        """长度(自定义含义)"""
        return int((self.x**2 + self.y**2)**0.5)
    
    def __getitem__(self, index):
        """索引访问"""
        if index == 0:
            return self.x
        elif index == 1:
            return self.y
        else:
            raise IndexError("索引超出范围")

# 使用特殊方法
v1 = Vector(2, 3)
v2 = Vector(1, 4)
v3 = v1 + v2  # 使用 __add__
print(v3)      # 输出: Vector(3, 7) 使用 __str__
print(len(v1)) # 输出: 3 使用 __len__
print(v1[0])   # 输出: 2 使用 __getitem__

属性装饰器

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age
    
    @property
    def name(self):
        """获取name属性"""
        return self._name
    
    @name.setter
    def name(self, value):
        """设置name属性"""
        if isinstance(value, str) and len(value) > 0:
            self._name = value
        else:
            raise ValueError("姓名必须是非空字符串")
    
    @property
    def age(self):
        """获取age属性"""
        return self._age
    
    @age.setter
    def age(self, value):
        """设置age属性"""
        if 0 <= value <= 150:
            self._age = value
        else:
            raise ValueError("年龄必须在0-150之间")

# 使用属性装饰器
person = Person("张三", 25)
print(person.name)  # 输出: 张三
person.name = "李四"  # 使用setter
person.age = 30     # 使用setter

抽象基类

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        """计算面积"""
        pass
    
    @abstractmethod
    def perimeter(self):
        """计算周长"""
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

# 使用抽象基类
rect = Rectangle(5, 3)
print(f"面积: {rect.area()}")       # 输出: 面积: 15
print(f"周长: {rect.perimeter()}")  # 输出: 周长: 16

最佳实践

  1. 命名规范: 类名使用驼峰命名法(CamelCase)
  2. 文档字符串: 为类和重要方法添加文档字符串
  3. 单一职责: 每个类应该只有一个主要职责
  4. 适度封装: 使用适当的访问控制(公有、保护、私有)
  5. 优先使用组合: 相比于继承,优先使用组合来复用代码

这些是 Python 类的基本概念和用法,掌握它们可以帮助你编写更加模块化、可维护的代码。