第十五篇:类与实例:面向对象编程基础
前言
面向对象的编程(OOP)是 Python 最重要的编程范式之一。本文讲解类的定义、实例的创建、构造方法 __init__、实例属性与方法绑定,以及 self 参数的含义。
什么是类和实例?
核心概念
class Dog:
pass
my_dog = Dog() # my_dog 是一个实例
your_dog = Dog() # another instance
# 类比:类 = 建筑设计图,实例 = 具体房屋
定义类的基本结构
class Dog:
"""表示一只狗"""
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
def bark(self): # 实例方法
print(f"{self.name} 汪汪叫!")
def info(self):
return f"{self.name}, {self.age}岁"
dog1 = Dog("旺财", 3)
dog2 = Dog("小花", 5)
print(dog1.info()) # 旺财,3 岁
dog1.bark() # 旺财汪汪叫!
self 参数详解
self 是什么?
self 代表实例本身,让你可以在方法中访问该实例的属性和其他方法。
class Person:
def __init__(self, name):
self.name = name
def greet(self):
print(f"你好,我是{self.name}")
def compare(self, other):
if self.name == other.name:
print(f"{self.name} 和 {other.name} 同名")
else:
print(f"{self.name} ≠ {other.name}")
alice = Person("Alice")
bob = Person("Bob")
alice.greet() # 你好,我是 Alice
alice.compare(bob) # Alice ≠ Bob
关键点:
self不是关键字,只是惯例- Python 自动传递
self,无需显式传入 self指向调用该方法的实例
实例属性 vs 类属性
class Student:
school = "阳光中学" # 类属性 - 所有实例共享
def __init__(self, name, score):
self.name = name # 实例属性 - 每个实例独立
self.score = score
s1 = Student("张三", 95)
s2 = Student("李四", 88)
print(s1.school) # 阳光中学
Student.school = "新阳光中学" # 修改影响所有实例
s1.score = 100 # 只影响 s1
动态添加/删除属性
cat = Cat("咪咪")
cat.color = "白色" # 动态添加
del cat.weight # 动态删除
魔术方法(特殊方法)
init 构造方法
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
rect = Rectangle(10, 5) # 创建时自动调用
print(rect.area()) # 50
str 和 repr 字符串表示
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"点 ({self.x}, {self.y})" # 用户友好
def __repr__(self):
return f"Point({self.x}, {self.y})" # 开发者调试用
p = Point(3, 4)
print(str(p)) # 点 (3, 4)
print(repr(p)) # Point(3, 4)
其他常用魔术方法速查
| 魔术方法 | 触发场景 | 示例 |
|---|---|---|
__len__ |
len(obj) |
返回长度 |
__add__ |
a + b |
加法运算 |
__eq__ |
a == b |
相等比较 |
__lt__ |
a < b |
小于比较 |
__hash__ |
hash(obj) |
哈希值 |
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 __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 * 3) # Vector(3, 6)
print(v1 == v2) # False
继承入门
代码复用
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
raise NotImplementedError("子类必须实现")
def info(self):
return f"{self.name}, {self.age}岁"
class Dog(Animal): # Dog 继承自 Animal
def __init__(self, name, age, breed):
super().__init__(name, age) # 调用父类构造
self.breed = breed
def speak(self):
return "汪汪汪!"
class Cat(Animal):
def __init__(self, name, age, color):
super().__init__(name, age)
self.color = color
def speak(self):
return "喵喵喵~"
dog = Dog("旺财", 3, "金毛")
cat = Cat("咪咪", 2, "白色")
print(dog.info()) # 旺财,3 岁
print(dog.speak()) # 汪汪汪!
super() 的作用
class Base:
def __init__(self, value):
self.value = value
print("Base.__init__")
class Child(Base):
def __init__(self, value, extra):
super().__init__(value) # 调用父类构造
self.extra = extra
print("Child.__init__")
child = Child(10, "test")
# Base.__init__ → Child.__init__
方法重写
class Vehicle:
def describe(self):
return "交通工具"
class Car(Vehicle):
def describe(self):
return "汽车 — 有轮子能跑"
class Bicycle(Vehicle):
def describe(self):
return "自行车 — 人力驱动"
for v in [Car(), Bicycle()]:
print(v.describe())
OOP 优势对比
# ❌ 面向过程:数据与逻辑分离
students_data = [{"name": "A", "score": 95}]
def get_avg(data): ...
# ✅ 面向对象:数据与行为绑定
class StudentDatabase:
def __init__(self, students):
self.students = students
def get_average(self): ...
def sort_by_score(self): ...
实战:学生管理系统
class Student:
def __init__(self, name, sid):
self.name = name
self.sid = sid
self.grades = {}
def add_grade(self, subject, grade):
self.grades[subject] = grade
def get_average(self):
if not self.grades:
return 0
return sum(self.grades.values()) / len(self.grades)
def __str__(self):
avg = self.get_average()
return f"{self.name} ({self.sid}) — 平均分:{avg:.1f}"
school = School("阳光中学")
s1 = Student("张三", "001")
s1.add_grade("数学", 95)
s1.add_grade("英语", 88)
school.add_student(s1)
school.display_all()
总结
- 类和实例 — 类是蓝图,实例是具体对象
- self 参数 — 指向实例本身的引用,用于访问属性和方法
- 实例属性 vs 类属性 — 实例属性独立,类属性共享
- 魔术方法 —
__init__构造、__str__/__repr__字符串表示 - 继承 — 子类扩展父类功能,使用
super()调用父类方法 - 方法重写 — 子类覆盖父类方法实现定制行为
- OOP 优势 — 数据与行为封装,提高代码复用性和可维护性
- 实战应用 — 学生管理系统的完整实现
下一篇文章将深入讲解访问限制:私有属性、封装机制与 getter/setter。
本文是 Python 教程系列的第十五篇。
