目录

前言

一、str__与__repr:搞定对象打印,区分用户视图与调试视图

核心概念

完整示例代码

开发避坑

二、常用魔法函数大全:初始化、比较运算、算数运算

1. 基础魔法函数总表

2. 比较运算符魔法函数

3. 算数运算魔法函数

三、组合类:一个类实例作为另一个类的属性(项目高频用法)

概念

实战案例 1:点与圆

实战案例 2:人物、汽车 ,武器多层组合(贴近业务开发)

进阶实战:角色战斗管理类(管理类 + 组合完整项目模板)

管理类核心设计思想

四、继承:代码复用,父类抽公共逻辑,子类扩展独有功能

基础概念

完整示例

项目使用场景

五、四大核心知识点总结(适配学生成绩管理系统开发)

六、配套实战问题答疑(对应你之前写系统踩过的坑)

结尾


前言

很多初学者学 Python 面向对象只会写简单class Person,遇到项目就踩坑:打印对象全是内存地址、多个管理类数据不互通、子类无法复用父类逻辑、对象比较失效。

本文结合课堂完整示例代码,从字符串魔法函数→运算符魔法函数→组合类→继承→管理类实战完整拆解,所有代码可直接运行,适配学生成绩管理系统开发场景,解决你开发中 90% 的 OOP 报错。

一、str__与__repr:搞定对象打印,区分用户视图与调试视图

核心概念

Python 打印对象默认输出内存地址,重写两个魔法函数自定义展示逻辑:

  1. __str__:面向普通用户,print(对象)str(对象)自动调用,输出简洁易懂文本;
  2. __repr__:面向开发者调试,交互式终端、对象放入列表 / 字典时自动触发,输出可重建对象的完整格式。

完整示例代码

python

运行

"""
直接打印实例对象 触发__str__
将实例对象放入list/dict容器 触发__repr__
repr(实例) 触发__repr__
str(实例) 触发__str__
"""
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        """开发者调试:完整参数,可直接复制创建对象"""
        return f"Person(name={self.name}, age={self.age})"

    def __str__(self):
        """普通用户:简洁可读信息"""
        return f"name: {self.name}, age: {self.age}"

p1 = Person("hus", 10)
print(p1)  # 调用__str__ → name: hus, age: 10
p2 = Person("hasd", 20)
print(p2)
l1 = [{p1:1},{p2:2}]
print(l1)  # 容器内对象调用__repr__

开发避坑

写管理系统时,学生、课程、成绩类必须同时重写两个方法,查看列表数据时不用再循环打印每个属性,直接打印列表即可看懂全部信息。

二、常用魔法函数大全:初始化、比较运算、算数运算

1. 基础魔法函数总表

表格

魔法方法 触发时机 作用
__init__ 创建实例自动执行 初始化实例属性,最核心
__str__ print/str() 用户友好字符串
__repr__ 容器、repr ()、调试 开发者调试字符串
__sizeof__ sys.getsizeof() 获取对象占用内存大小
__dir__ dir (对象) 自省,查看对象所有属性方法

2. 比较运算符魔法函数

默认对象比较是对比内存地址,重写后可按年龄、分数、学号自定义对比规则:

python

运行

class MyClass:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    # 大于 >
    def __gt__(self, other):
        return self.age > other.age
    # 大于等于 >=
    def __ge__(self, other):
        return self.age >= other.age
    # 小于 <
    def __lt__(self, other):
        return self.age < other.age
    # 小于等于 <=
    def __le__(self, other):
        return self.age <= other.age
    # 相等 ==
    def __eq__(self, other):
        return self.age == other.age
    # 不等 !=
    def __ne__(self, other):
        return self.age != other.age

p1 = MyClass("张三", 10)
p2 = MyClass("李七", 2)
print(p1 == p2)  # False,按age对比而非内存地址
print(p1 > p2)   # True

3. 算数运算魔法函数

__add__ __sub__ __mul__ __truediv__等,可实现对象直接加减乘除,比如两个分数对象求和、学生总分相加。

三、组合类:一个类实例作为另一个类的属性(项目高频用法)

概念

组合 = 封装延伸,把一个完整对象作为另一个类的成员属性,表达「包含关系」,比如:

  • 圆包含坐标点 Point → Circle
  • 人包含汽车、武器 Person → Car + Weapon 这也是你成绩管理系统的核心结构:成绩类包含学生实例、课程实例。

实战案例 1:点与圆

python

运行

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

class Circle:
    # 组合:传入Point实例作为圆心
    def __init__(self, center: Point, r):
        self.center = center
        self.r = r
    def __str__(self):
        return f"圆心{self.center}, 半径{self.r}"

p1 = Point(1, 2)
c1 = Circle(p1, 2)
print(c1)  # 圆心(1,2), 半径2
# 访问内部对象属性
print(c1.center.x)

实战案例 2:人物、汽车 ,武器多层组合(贴近业务开发)

 2. 编写汽车类(颜色,速度)
 编写人 类(名字 汽车实例)

编写武器类(类型 ,属性)
 编写列表 放入 3个人 遍历列表依次打印每个人的信息

python

运行

class Car:
    def __init__(self, color = "red", speed = 3):
        self.color = color
        self.speed = speed
    def __str__(self):
        return f"Car({self.color},{self.speed})"

class Weapon:
    def __init__(self,kind,level):
        self.kind = kind
        self.level = level
    def add_level(self):
        self.level += 1
    def __str__(self):
        return f"Weapon{self.kind,self.level}"

# Person组合Car和Weapon两个对象
class Person:
    def __init__(self,name,car:Car , weapon:Weapon):
        self.name = name
        self.car = car
        self.weapon = weapon
    def __str__(self):
        return f"Person({self.name},{self.car},{self.weapon})"

c1 = Car()
w1 = Weapon("菜刀",2)
p1 = Person("张三",c1,w1)
p1.weapon.add_level()
print(p1)

组合类如果在内部__init__重新 new 管理器,会生成独立数据空间:

python

运行

# 错误写法:每次创建ScoreManage都新建空课程管理器,数据隔离
class ScoreManage:
    def __init__(self):
        self.course_manage = CourseManagement() # 全新空对象

正确方案:外部传入已初始化的管理器实例,共享同一份课程、学生数据

python

运行

# 构造函数接收外部管理器实例
def __init__(self, student_mgr, course_mgr):
    self.student_manage = student_mgr
    self.course_manage = course_mgr
# 主程序只创建一次
stu_mgr = StudentManage()
course_mgr = CourseManagement()
score_mgr = ScoreManage(stu_mgr, course_mgr)

进阶实战:角色战斗管理类(管理类 + 组合完整项目模板)

管理类核心逻辑:用列表统一存储对象,实现增删改查、批量操作,学生 / 课程管理系统完全复用这套模板:

# .编写角色类,拥有血量【3000,5000】和攻击力【100,300】以及必要方法
# 随机10个角色(血量,攻击力随机)放入列表
# 列表中的角色依次攻击下一个(最后一个攻击第一个)
# 角色死亡后移除列表,输出最后存活角色信息

python

运行

import random
class Character:
    def __init__(self, name=0, hp=0, attack=0):
        self.name = name
        self.hp = hp
        self.attack = attack
    def attack_action(self, other):
        other.hp -= self.attack
    def is_alive(self):
        return self.hp > 0
    def __str__(self):
        return f"角色{self.name} 血量{self.hp} 攻击{self.attack}"

# 管理类:统一管理多个Character实例
class CharacterManager:
    def __init__(self):
        self.characters = []
    # 批量创建角色
    def create_characters(self, n=10):
        for i in range(1, n + 1):
            c = Character(i)
            c.hp = random.randint(3000,5000)
            c.attack = random.randint(100,300)
            self.characters.append(c)
        return self.characters
    # 清理死亡角色(倒序删除避免索引错乱)
    def clear_dead(self):
        for i in range(len(self.characters)-1, -1, -1):
            if not self.characters[i].is_alive():
                print(f"{self.characters[i]} 阵亡")
                self.characters.pop(i)
    # 循环对战逻辑
    def battle_loop(self):
        round_cnt = 1
        while len(self.characters) > 1:
            print(f"=====第{round_cnt}轮战斗=====")
            # 循环攻击
            for i in range(len(self.characters)):
                attacker = self.characters[i]
                target = self.characters[(i+1) % len(self.characters)]
                if attacker.is_alive():
                    attacker.attack_action(target)
            self.clear_dead()
            round_cnt += 1
        if self.characters:
            print(f"战斗结束,胜利者:{self.characters[0]}")
        else:
            print"全部阵亡"

cm = CharacterManager()
cm.create_characters(5)
cm.battle_loop()

管理类核心设计思想

文档原文:管理类:管理实例,将类实例存入 list,遍历列表实现增删改查,学生管理、课程管理、成绩管理都遵循这个模式:

  1. 管理器内置self.datas = []存储所有对象;
  2. add_xxx:创建实例 append 进列表;
  3. get_all:循环打印列表全部数据;
  4. get_by_id:遍历列表匹配 id 返回指定对象;
  5. update/delete:找到对象修改属性或 pop 删除。

四、继承:代码复用,父类抽公共逻辑,子类扩展独有功能

基础概念

Python 所有类默认继承object,语法class 子类(父类)super()调用父类构造方法,复用父类属性与方法,避免重复写代码。 父类 = 基类 / 超类,子类 = 派生类。

完整示例

python

运行

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def get_info(self):
        return f"普通人类:姓名{self.name},年龄{self.age}"
    def __str__(self):
        return "Person基础类"

# SuperPerson继承Person
class SuperPerson(Person):
    def __init__(self, name, age, skill):
        # 调用父类初始化,复用name、age属性
        super().__init__(name, age)
        # 子类独有属性
        self.skill = skill
    # 重写父类方法,扩展输出
    def get_info(self):
        # 复用父类原有文本,追加独有技能
        return f"超人{super().get_info()},专属技能:{self.skill}"

sp1 = SuperPerson("ook", 19, "飞行")
print(sp1.get_info())

项目使用场景

开发管理系统时,可以抽公共父类BaseModel,封装 id、name、__str____repr__,学生、课程、成绩子类直接继承,不用重复写基础属性与打印方法。

五、四大核心知识点总结(适配学生成绩管理系统开发)

  1. 字符串魔法函数 __str__给用户看,__repr__给调试看,所有实体类(学生、课程、成绩)必须重写,解决打印对象显示内存地址问题;
  2. 运算符魔法函数 重写__eq____gt__,实现按学号、分数直接对比对象,简化查询、排序逻辑;
  3. 组合类(重中之重)
    • 表达「包含关系」,成绩类包含学生、课程实例;
    • 管理类传参注入,解决多模块数据隔离(你之前找不到课程的核心 bug);
    • 管理类标准模板:列表存储实例,统一实现增删改查;
  4. 继承 抽取公共逻辑到父类,减少重复代码,提升项目可维护性。

六、配套实战问题答疑(对应你之前写系统踩过的坑)

  1. 为什么添加成绩提示无课程? ScoreManage 内部新建独立 CourseManagement 实例,两个列表数据隔离,采用组合注入方式共享管理器实例即可修复;
  2. 修改信息一直卡死输入年龄? 获取性别函数错误转换 int,输入文字触发异常无限循环,去除 int 转换并增加输入校验;
  3. 打印学生列表只显示内存地址? 未重写__str____repr__,给 Student 类补充两个字符串魔法函数;
  4. 两个学生明明学号相同,==判断不相等? 默认对比内存地址,重写__eq__魔法函数,按学号判断相等。

结尾

本文覆盖从基础魔法函数到项目级组合、继承、管理类全部核心代码,是 Python 面向对象从小案例过渡到学生管理系统、游戏角色系统的完整学习路径。掌握这套逻辑后,再开发任何小型 OOP 项目都能规避绝大多数数据互通、打印、查询类 bug。

Logo

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

更多推荐