面向对象

定义与创建类

class Dog:
    """一个简单的 Dog 类"""
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name} says Woof!")

# 创建实例 (实例化)
my_dog = Dog("Buddy", 3)

__init__方法(构造函数)

  • 作用:在创建对象时自动调用,用于初始化对象的属性。

  • 参数:

    • self:指向创建的实例本身,是方法的第一个参数(约定俗成,可重命名但不推荐)

    • 其他参数:用于接收创建实例时传入的值。

  • 注意:不要返回非None的值(除非是__new__),否则会引发TypeError

类的属性和方法

实例属性 & 类属性

  • 实例属性:属于对象,每个对象单独维护一份。

  • 类属性:属于类,所有对象共享。

class Person:
  species = "Human"	# 类属性

  def __init__(self, name):
    self.name = name # 实例属性

方法分类

实例方法

class Example:
    count = 0

    def instance_method(self):  # 实例方法
        return "instance method", self

类方法(Class Methods)

使用@classmethod装饰器定义,第一个参数是cls,指向类本身(而非实例)。不能访问实例守护星,可以访问类属性。长用于创建替代的构造函数(工厂方法)。

class Person:
    species = "Homo sapiens"

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

    @classmethod
    def form_string(cls, person_str):
        name, age = person_str.split("-")
        return cls(name, int(age))  # clas 指向 Person


person = Person.form_string("Alice-30")

静态方法

使用@staticmethod装饰器定义,没有selfcls参数。与类相关,但不操作类或实例数据。更像是放在类里的普通函数,用于组织代码。

class Person:
    @staticmethod
    def is_adult(age):
        return age >= 18


print(Person.is_adult(20))
print(Person().is_adult(20))

特殊方法(魔术方法 Magic Methods)

常用魔术方法总结:

方法
作用

__init__

构造方法

__del__

析构方法

__str__

打印对象的友好表示

__repr__

对象的官方表示(调试用)

__len__

len(obj) 调用

__getitem__

索引访问 obj[key]

__setitem__

赋值 obj[key] = val

__delitem__

删除 del obj[key]

__iter__

返回迭代器

__next__

迭代取值

__call__

使对象可调用

__enter__ / __exit__

上下文管理协议(with 语句)

__eq__, __lt__, __gt__

比较运算符重载

__add__, __sub__

运算符重载

__new__

控制实例的创建(单例模式常用)

封装

将数据(属性)和操作数据的代码(方法)捆绑在一起,并隐藏内部实现细节。

Python 中的实现:

  • 约定:使用单下划线_attribute表示“受保护”的属性/方法(内部使用,不推荐外部直接访问)

  • 名称改写:使用双下划线__attribute定义“私有”属性/方法。Python 会将其重命名为_ClassName.__attribute,防止意外覆盖,单并非绝对私有。

  • 属性装饰器:提供受控的访问接口(getter/setter)

class A:
    def __init__(self):
        self.public = "公开"
        self._protected = "受保护"
        self.__private = "私有"


a = A()
print(a.public)  # ✅输出:公开
print(a._protected)  # ⚠️输出:受保护 (约定不建议外部访问)
# print(a.__private)  # ❌报错
print(a._A__private)  # Name Mangling 后可访问

继承

一个类(子类/派生类)可以继承另外一个类(父类/基类/超类)的属性和方法,实现代码复用。

  • 特点

    • 子类自动拥有父类的所有共有属性和方法。

    • 子类可以添加新的属性和方法。

    • 子类可以重写(Override)父类的方法,提供自己的实现。

  • super()函数:

    • 用于在子类中调用父类的方法。

    • 避免硬编码父类名,提供代码灵活性和可维护性。

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

    def speak(self):
        pass

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类 __init__
        self.breed = breed

    def speak(self): # 重写 speak 方法
        return f"{self.name} says Woof!"

多继承

一个子类可以继承多个父类。

语法:class ChildClass(Parent1, Parent2, ...)

方法解析顺序:

  • Python 使用 C3 线性化算法确定属性和方法的查找顺序。

  • 可以通过ClassName.__mro__ClassName.mro()查看 MRO

  • 钻石继承问题:当多个父类继承同一个祖先类时,MRO 确保祖先类的方法只被调用一次。

多态(Polymorphism)

不同类对象实现同名方法,调用时体现不同的行为。

class Cat():
    def speak(self):
        return "Meow"


class Dog:
    def speak(self):
        return "Woof"


def make_sound(animal):
    print(animal.speak())


make_sound(Cat())  # Meow
make_sound(Dog())  # Woof

属性装饰器(Property)

将方法伪装成属性,提供对私有属性的安全访问(getter,setter,deleter)

  • @property:定义getter方法,访问时像属性一样(obj.attr)

  • @attr.setter:定义setter方法,赋值时调用(obj.attr = value)

  • @atter.deleter:定义deleter方法,删除时调用(del obj.attr)

class Circle:
    def __init__(self, radius):
        self._radius = radius  # 约定私有属性

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value

    @property
    def area(self):
        return 2.14159 * self._radius ** 2


circle = Circle(5)
print(circle.radius)  # 5 (调用 getter)
circle.radius = 10  # 调用 setter
print(circle.area)  # 314.159 (只读属性)

抽象基类(ABC - Abstract Base Class)

定义接口规范,强制子类必须实现某些方法。

继承abc.ABC或使用@abstractmethod装饰器。用@abstractmethod装饰的方法在子类中必须被重写。包含抽象方法的类不能被实例化。

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)

# shape = Shape() # 错误! 不能实例化抽象类
rect = Rectangle(3, 4) # 正确

最后更新于