Python3 面向对象

Python3 面向对象编程(OOP)


🎯 学习目标

掌握 Python 中面向对象编程的基本概念和实现方式,包括类与对象的定义、属性与方法的使用、继承与多态等核心机制。能够在实际项目中设计并实现结构清晰、可维护性强的类结构,理解封装、继承、多态三大面向对象特性。


🔑 核心重点

分类 内容
类与对象 定义类 class,创建对象实例
属性与方法 实例属性、类属性、构造方法 __init__()、实例方法
封装 通过 ___ 控制访问权限
继承 父类与子类关系,方法重写
多态 同一接口支持不同行为
特殊方法 __str__(), __repr__(), __len__()

📚 详细讲解

一、什么是面向对象编程?

面向对象编程(Object-Oriented Programming, OOP) 是一种以“对象”为中心的程序设计方法,强调将数据(属性)和操作(方法)封装在一起。

✅ 基本概念:

  • 类(Class):模板或蓝图,描述一类对象的共同特征。
  • 对象(Object / Instance):类的具体实例。
  • 属性(Attribute):对象的数据。
  • 方法(Method):对象的行为。

二、定义类与创建对象

✅ 示例:定义一个 Person

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

    def greet(self):
        print(f"你好,我叫 {self.name},今年 {self.age} 岁。")

# 创建对象
p1 = Person("张三", 25)
p1.greet()

📌 输出:

你好,我叫 张三,今年 25 岁。

三、类属性与实例属性

  • 类属性:属于类本身,所有实例共享。
  • 实例属性:属于每个实例独立存在。

✅ 示例:

class Dog:
    species = "犬科动物"  # 类属性

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

d1 = Dog("小白")
d2 = Dog("小黑")

print(d1.species)  # 输出:犬科动物
print(d2.species)

Dog.species = "哺乳动物"
print(d1.species)  # 输出:哺乳动物

四、封装:控制访问权限

  • 单下划线 _:约定为受保护成员(非强制)
  • 双下划线 __:私有成员(名称改写机制)

✅ 示例:

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 私有属性

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def get_balance(self):
        return self.__balance

acc = BankAccount(1000)
acc.deposit(500)
print(acc.get_balance())  # 输出:1500

📌 注意:__balance 无法直接访问,如需修改应通过方法。


五、继承:类之间的父子关系

✅ 示例:父类 Animal 与子类 Cat

class Animal:
    def speak(self):
        print("动物发出声音")

class Cat(Animal):  # 继承 Animal
    def speak(self):
        print("喵~")

c = Cat()
c.speak()  # 输出:喵~

📌 子类可以继承父类的方法,并可以重写它们。


六、super() 函数:调用父类方法

class Parent:
    def __init__(self, name):
        print("Parent 初始化")
        self.name = name

class Child(Parent):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类初始化方法
        self.age = age

七、多态:统一接口,不同实现

✅ 示例:

def make_sound(animal):
    animal.speak()

class Dog:
    def speak(self):
        print("汪汪!")

class Cat:
    def speak(self):
        print("喵~")

make_sound(Dog())  # 输出:汪汪!
make_sound(Cat())  # 输出:喵~

📌 多态使得函数能接受多种类型的参数,执行相应行为。


八、特殊方法(Magic Methods)

Python 提供了丰富的内置“魔法方法”,用于自定义类的行为。

方法名 用途说明
__init__() 构造方法
__str__() 返回用户友好的字符串表示
__repr__() 返回开发者友好的字符串表示
__len__() 自定义 len() 的行为
__add__() 自定义 + 运算符
__call__() 让对象像函数一样被调用

✅ 示例:自定义 __str__

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return f"{self.title} - {self.author}"

b = Book("Python 编程", "李明")
print(b)  # 输出:Python 编程 - 李明

⚠️ 注意事项

  • 类名通常采用大驼峰命名法(如 StudentInfo
  • 不要滥用继承,优先组合优于继承
  • 尽量避免直接访问私有属性(应通过方法)
  • 使用 isinstance(obj, cls) 判断对象类型
  • 避免在类中定义过多全局变量或状态

🧪 实际案例分析

📌 场景:构建一个“学生管理系统”

功能需求:

  • 学生类(姓名、年龄、成绩)
  • 教师类(继承于人员类)
  • 成绩管理功能(添加、查询、排序)

示例代码:

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

class Student(Person):
    def __init__(self, name, age, grade):
        super().__init__(name, age)
        self.grade = grade

    def __str__(self):
        return f"{self.name}({self.age}岁):{self.grade}分"

students = [
    Student("张三", 20, 85),
    Student("李四", 22, 92),
    Student("王五", 19, 78)
]

for s in sorted(students, key=lambda x: x.grade, reverse=True):
    print(s)

📌 输出示例:

李四(22岁):92分
张三(20岁):85分
王五(19岁):78分

🧩 拓展练习(动手实践)

  1. 设计一个 Rectangle 类,包含长和宽,提供计算面积和周长的方法。
  2. 创建一个 Circle 类继承 Shape 抽象类,实现 area() 方法。
  3. 编写一个“银行账户管理系统”,支持存款、取款、转账等操作。
  4. 实现一个“图书管理系统”,支持借阅、归还、查询书籍信息。
  5. 使用 __call__ 方法让类实例可以像函数一样调用,模拟计算器功能。

📚 推荐阅读


🧭 下一步建议

  • 下一章学习内容:《Python3 高级面向对象编程》
  • 掌握继承进阶(多重继承、MRO)、抽象基类(ABC)
  • 学会使用装饰器定义静态方法、类方法
  • 理解元类(metaclass)和单例模式
  • 掌握封装与模块化设计原则,提升代码复用性

如果你希望我为你提供:

  • Python 面向对象速查表 PDF(含类结构+语法+常用魔术方法)
  • 更多实战项目练习题(如银行系统、图书管理系统、游戏角色设计等)
  • 视频教学资源推荐(中文讲解)
  • 如何结合 abc 模块实现抽象基类(Abstract Base Class)

欢迎随时告诉我 😊

类的专有方法(Magic Methods / 特殊方法)


在 Python 中,类的专有方法(也叫魔法方法或特殊方法) 是以双下划线 __ 开头和结尾的方法,它们具有特殊的语义,用于实现对象的内置行为。这些方法允许你自定义类在使用某些操作符或内置函数时的表现方式。


✅ 常见专有方法一览表

方法名 调用时机/用途说明
__init__(self, ...) 构造方法,在创建对象时自动调用
__new__(cls, ...) 创建实例的工厂方法(在 __init__ 之前调用)
__del__(self) 析构方法,在对象被销毁时调用
__str__(self) 定义 str(obj) 的返回值,用于用户友好输出
__repr__(self) 定义 repr(obj) 的返回值,用于开发者调试
__len__(self) 定义 len(obj) 的行为
__add__(self, other) 定义 + 运算符的行为
__sub__(self, other) 定义 - 运算符的行为
__mul__(self, other) 定义 * 运算符的行为
__call__(self, ...) 让对象像函数一样可调用
__getitem__(self, key) 定义 obj[key] 的行为
__setitem__(self, key, value) 定义 obj[key] = value 的行为
__contains__(self, item) 定义 in 操作符的行为

✅ 示例详解

1. __str__()__repr__()

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return f"{self.title} - {self.author}"

    def __repr__(self):
        return f"Book(title='{self.title}', author='{self.author}')"

book = Book("Python编程", "李明")
print(str(book))    # 输出:Python编程 - 李明
print(repr(book))   # 输出:Book(title='Python编程', author='李明')

📌 使用建议:

  • __str__() 更适合终端用户阅读
  • __repr__() 更适合开发者调试、日志记录

2. __len__() 自定义长度

class MyList:
    def __init__(self, data):
        self.data = data

    def __len__(self):
        return len(self.data)

lst = MyList([1, 2, 3])
print(len(lst))  # 输出:3

3. __add__() 支持加法运算

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    def __str__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3)  # 输出:Vector(4, 6)

4. __call__() 让对象可调用

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

    def __call__(self):
        print(f"你好,{self.name}!")

greet = Greeter("小明")
greet()  # 输出:你好,小明!

📌 应用场景:装饰器、回调函数、状态保持的函数对象等。


5. __getitem__()__setitem__() 模拟列表/字典行为

class MyDict:
    def __init__(self):
        self.data = {}

    def __getitem__(self, key):
        return self.data.get(key)

    def __setitem__(self, key, value):
        self.data[key] = value

d = MyDict()
d["name"] = "张三"
print(d["name"])  # 输出:张三

⚠️ 注意事项

  • 魔法方法不应随意重写,除非你确实需要改变其默认行为
  • 不要滥用 __call__(),否则会让代码难以理解
  • 尽量保持魔法方法的语义一致性,避免“黑魔法”式编码
  • 多个魔法方法配合使用时要注意逻辑顺序和边界情况处理

🧪 实际案例分析

场景:构建一个支持数学运算的二维点类

import math

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    def __abs__(self):
        return math.hypot(self.x, self.y)

    def __str__(self):
        return f"Point({self.x}, {self.y})"

p1 = Point(3, 4)
p2 = Point(1, 2)
p3 = p1 + p2
print(p3)           # 输出:Point(4, 6)
print(abs(p1))      # 输出:5.0(3,4的欧几里得距离)

📌 优势:

  • 提供了自然的数学表达方式
  • 可读性强,易于扩展
  • 可与其它数值类型进行混合运算(需进一步实现)

🧩 拓展练习(动手实践)

  1. 实现一个 Fraction 类,表示分数,并支持加减乘除操作。
  2. 创建一个 Matrix 矩阵类,支持矩阵相加、相乘等操作。
  3. 设计一个 Person 类,支持通过 p['age'] 获取属性。
  4. 编写一个 Logger 类,使其可以像函数一样调用并记录日志信息。
  5. 使用 __len__()__bool__() 实现一个自定义容器类,并控制其真假判断。

📚 推荐阅读


🧭 下一步建议

  • 学习如何使用 @property@staticmethod 等装饰器增强类功能
  • 理解抽象基类(Abstract Base Class)和接口设计
  • 掌握元类(metaclass)的基本概念与应用场景
  • 结合项目实战,深入理解封装、继承、多态的实际意义

如果你希望我为你提供:

  • Python 魔法方法速查表 PDF(含所有常用方法+示例)
  • 更多实战项目练习题(如向量运算、自定义容器类、日志记录器等)
  • 视频教学资源推荐(中文讲解)
  • 如何结合 abc 模块实现接口和抽象类

欢迎随时告诉我 😊

posted @ 2025-06-03 00:06  红尘过客2022  阅读(48)  评论(0)    收藏  举报