Chapter 07

类

Python基础 · 面向对象编程的核心

欢迎关注微信公众号

coder程

本章目录

1. 引言:为什么需要类

面向过程用 函数 处理数据,面向对象用 类 把数据和行为 封装 在一起。

# 面向过程:数据和行为分离 dog_name = "Buddy" dog_age = 3 def dog_bark(name): print(f"{name} says: 汪!") dog_bark(dog_name)
# 面向对象:数据和行为绑定 class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(f"{self.name} says: 汪!") buddy = Dog("Buddy", 3) buddy.bark() # Buddy says: 汪!

当数据和行为 天然关联 时,面向对象让代码更有组织、更易扩展。

2. 类的定义

类是对象的 蓝图/模板 ,定义了对象有哪些 属性 (数据)和 方法 (行为)。

class Student: # 类属性:所有实例共享 school = "Python学院" # 构造方法:创建实例时自动调用 def __init__(self, name, age): self.name = name # 实例属性 self.age = age # 实例方法 def introduce(self): return f"我是{self.name},{self.age}岁" # 类方法 @classmethod def from_birth_year(cls, name, birth_year): age = 2024 - birth_year return cls(name, age)

2. 实例属性、类属性与特殊方法

class Circle: pi = 3.14159 # 类属性 def __init__(self, radius): self.radius = radius def area(self): return self.pi * self.radius ** 2 def __str__(self): # 打印对象时的友好输出 return f"Circle(radius={self.radius})" def __repr__(self): # 交互式环境中的表示 return f"Circle({self.radius})" def __eq__(self, other): # == 比较逻辑 return self.radius == other.radius

魔术方法(Dunder Methods) :以双下划线包围,让对象像内置类型一样自然。

3. 创建实例

类本身不会创建数据,需要 实例化 (调用类名)产生对象。

# 创建实例 s1 = Student("Alice", 20) s2 = Student("Bob", 22) # 访问属性 print(s1.name) # Alice print(s1.school) # Python学院(继承自类) # 调用方法 print(s1.introduce()) # 通过类方法创建 s3 = Student.from_birth_year("Carol", 2000)

动态添加属性 :Python 允许运行时给实例添加新属性(但不推荐滥用)。

s1.hobby = "编程" print(s1.hobby) # 编程(仅 s1 有,不影响 s2)

3. 封装与属性装饰器

封装 :隐藏内部实现,通过公开接口交互。Python 用 命名约定 (单下划线)表示"私有"。

class BankAccount: def __init__(self, owner, balance=0): self.owner = owner self._balance = balance # _ 前缀:约定私有 def deposit(self, amount): if amount > 0: self._balance += amount def get_balance(self): return self._balance acc = BankAccount("Alice", 1000) acc.deposit(500) print(acc.get_balance()) # 1500

@property :把方法变成属性一样访问。

@property def balance(self): return self._balance # 使用:acc.balance 而不是 acc.get_balance()

4. 类的继承

继承 :子类自动拥有父类的属性和方法,同时可 扩展 或 重写 。

class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError("子类必须实现") class Dog(Animal): # Dog 继承 Animal def speak(self): return f"{self.name} says: 汪!" class Cat(Animal): # Cat 继承 Animal def speak(self): return f"{self.name} says: 喵~" d = Dog("Buddy") c = Cat("Kitty") print(d.speak()) # Buddy says: 汪! print(c.speak()) # Kitty says: 喵~

4. super() 与多继承

super() :调用父类的方法,避免显式指定父类名。

class Employee: def __init__(self, name, salary): self.name = name self.salary = salary class Manager(Employee): def __init__(self, name, salary, department): super().__init__(name, salary) self.department = department m = Manager("Alice", 50000, "IT")

多继承 :Python 支持一个子类继承多个父类,按 MRO(方法解析顺序) 查找。

class A: def method(self): print("A") class B(A): def method(self): print("B") class C(A): def method(self): print("C") class D(B, C): # 多继承 pass d = D() d.method() # B(按 MRO 顺序) print(D.__mro__) # 查看解析顺序

4. 多态 — 同一接口,不同表现

多态让不同的类对同一消息做出 不同的响应 。Python 作为动态语言天然支持。

def animal_concert(animals): for animal in animals: print(animal.speak()) animals = [Dog("Buddy"), Cat("Kitty")] animal_concert(animals) # 输出: # Buddy says: 汪! # Kitty says: 喵~

鸭子类型 :Python 不检查类型,只关心对象是否有需要的方法。

"如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子。"

常用魔术方法速查

方法 触发场景
__init__ 对象初始化
__str__ print(obj) / str(obj)
__repr__ 交互式环境 / repr(obj)
__eq__ obj1 == obj2
__lt__ obj1 < obj2
__len__ len(obj)
__getitem__ obj[key]
__call__ obj() 像函数一样调用

综合练习:图书管理系统

class Book: def __init__(self, title, author, isbn): self.title = title self.author = author self.isbn = isbn self._borrowed = False def borrow(self): if self._borrowed: print(f"《{self.title}》已被借出") else: self._borrowed = True print(f"成功借阅《{self.title}》") def __str__(self): status = "已借出" if self._borrowed else "在馆" return f"《{self.title}》({status})" class EBook(Book): def __init__(self, title, author, isbn, format): super().__init__(title, author, isbn) self.format = format def __str__(self): return f"[电子书] {super().__str__()} [{self.format}]"

本章总结

下一章 ▶