Python中面向对象基础
Python 面向对象编程基础
本文档系统讲解 Python 面向对象编程(OOP)的核心知识,从零基础入门到实际应用。
一、面向对象基础概念
1.1 什么是面向对象编程
面向对象编程(Object-Oriented Programming,OOP) 是一种编程范式,它将数据和操作数据的方法封装在一起,形成"对象"。
核心思想:
- 类(Class):对象的蓝图/模板,定义了对象的属性和方法
- 对象(Object):类的实例,是具体存在的实体
- 封装(Encapsulation):将数据和方法包装在一起
- 继承(Inheritance):子类继承父类的特性
- 多态(Polymorphism):同一操作作用于不同对象产生不同结果
1.2 类与对象的关系
类(Class) 对象(Object)
↓ ↓
设计图纸 → 具体的房子
模具 → 生产的产品
模板 → 实际的实例
类比理解:
- 类 就像汽车的"设计图纸",定义了汽车应该有什么(属性:颜色、品牌)和能做什么(方法:启动、刹车)
- 对象 就是根据图纸造出来的"具体汽车",比如"一辆红色的宝马"
1.3 为什么要用面向对象
| 优点 | 说明 |
|---|---|
| 代码复用 | 通过继承减少重复代码 |
| 易于维护 | 模块化设计,修改一处不影响全局 |
| 可扩展性 | 新增功能只需添加新类 |
| 贴近现实 | 用对象模拟现实世界的事物 |
二、定义类与创建对象
2.1 基本语法
使用 class 关键字定义类:
class 类名:
"""类的文档字符串"""
# 类属性(所有对象共享)
类属性 = 值
# 构造方法
def __init__(self, 参数):
# 实例属性(每个对象独立)
self.属性名 = 参数
# 实例方法
def 方法名(self, 参数):
# 方法体
pass
2.2 第一个类
class Dog:
"""狗狗类"""
# 类属性:所有狗共享
species = "Canis familiaris"
def __init__(self, name, age):
"""构造方法:创建对象时自动调用"""
self.name = name # 实例属性
self.age = age # 实例属性
def bark(self):
"""狗叫方法"""
return f"{self.name} says: 汪汪!"
def introduce(self):
"""自我介绍"""
return f"我是{self.name},今年{self.age}岁"
# 创建对象(实例化)
dog1 = Dog("旺财", 3)
dog2 = Dog("来福", 2)
# 访问属性和方法
print(dog1.name) # 旺财
print(dog1.bark()) # 旺财 says: 汪汪!
print(dog1.introduce()) # 我是旺财,今年3岁
print(dog2.name) # 来福
print(dog2.bark()) # 来福 says: 汪汪!
2.3 self 是什么
self 代表当前对象本身,是实例方法的第一个参数(必须写,但调用时不用传)。
class Person:
def __init__(self, name):
self.name = name # self.name 表示对象的 name 属性
def say_hello(self):
# self 让方法知道是哪个对象在调用它
print(f"你好,我是{self.name}")
p = Person("张三")
p.say_hello() # 等价于 Person.say_hello(p)
理解 self:
self就是对象自己- 通过
self.属性访问对象的属性 - 通过
self.方法()调用对象的其他方法
三、属性详解
3.1 类属性 vs 实例属性
| 特性 | 类属性 | 实例属性 |
|---|---|---|
| 定义位置 | 类内部,方法外部 | __init__ 中,用 self. 定义 |
| 归属 | 属于类,所有对象共享 | 属于对象,每个对象独立 |
| 访问方式 | 类名.属性 或 对象.属性 |
对象.属性 |
| 修改影响 | 影响所有对象 | 只影响当前对象 |
class Student:
# 类属性:所有学生共享
school = "北京大学"
student_count = 0
def __init__(self, name):
# 实例属性:每个学生独立
self.name = name
self.score = 0
Student.student_count += 1 # 修改类属性
# 创建学生
s1 = Student("张三")
s2 = Student("李四")
# 访问类属性
print(Student.school) # 北京大学
print(s1.school) # 北京大学
print(s2.school) # 北京大学
print(Student.student_count) # 2
# 访问实例属性
print(s1.name) # 张三
print(s2.name) # 李四
# 修改类属性
Student.school = "清华大学"
print(s1.school) # 清华大学(所有对象都变了)
# 修改实例属性
s1.score = 90
print(s1.score) # 90
print(s2.score) # 0(s2 没变)
3.2 动态添加属性
Python 是动态语言,可以给对象动态添加属性:
class Cat:
def __init__(self, name):
self.name = name
cat = Cat("咪咪")
# 动态添加属性
cat.color = "白色"
cat.age = 2
print(cat.color) # 白色
print(cat.age) # 2
注意:动态添加的属性只属于当前对象,不影响其他对象。
四、方法详解
4.1 实例方法
实例方法是最常见的方法,第一个参数必须是 self,只能通过对象调用。
class Calculator:
def __init__(self):
self.result = 0
def add(self, num):
"""实例方法"""
self.result += num
return self.result
def subtract(self, num):
"""实例方法"""
self.result -= num
return self.result
def reset(self):
"""重置"""
self.result = 0
calc = Calculator()
print(calc.add(5)) # 5
print(calc.add(3)) # 8
print(calc.subtract(2)) # 6
4.2 类方法
类方法使用 @classmethod 装饰器,第一个参数是 cls(代表类本身),可以通过类或对象调用。
class DateUtil:
"""日期工具类"""
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_string):
"""类方法:从字符串创建对象"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day)
@classmethod
def today(cls):
"""类方法:获取今天的日期对象"""
import datetime
now = datetime.datetime.now()
return cls(now.year, now.month, now.day)
def show(self):
return f"{self.year}-{self.month:02d}-{self.day:02d}"
# 使用类方法创建对象
date1 = DateUtil.from_string("2024-05-20")
print(date1.show()) # 2024-05-20
date2 = DateUtil.today()
print(date2.show()) # 2024-XX-XX(当前日期)
4.3 静态方法
静态方法使用 @staticmethod 装饰器,不需要 self 或 cls 参数,与类和对象无关,只是逻辑上属于这个类。
class MathUtil:
"""数学工具类"""
@staticmethod
def is_prime(n):
"""静态方法:判断是否为素数"""
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
@staticmethod
def factorial(n):
"""静态方法:计算阶乘"""
if n <= 1:
return 1
return n * MathUtil.factorial(n - 1)
# 直接通过类调用(不需要创建对象)
print(MathUtil.is_prime(17)) # True
print(MathUtil.is_prime(18)) # False
print(MathUtil.factorial(5)) # 120
# 也可以通过对象调用(不推荐)
util = MathUtil()
print(util.is_prime(7)) # True
4.4 三种方法对比
| 方法类型 | 装饰器 | 第一个参数 | 调用方式 | 用途 |
|---|---|---|---|---|
| 实例方法 | 无 | self |
对象.方法() | 操作对象数据 |
| 类方法 | @classmethod |
cls |
类.方法() 或 对象.方法() | 操作类数据、创建对象 |
| 静态方法 | @staticmethod |
无 | 类.方法() 或 对象.方法() | 独立功能、工具函数 |
五、构造函数与析构函数
5.1 构造函数 init
构造函数在创建对象时自动调用,用于初始化对象的属性。
class Book:
def __init__(self, title, author, price):
"""构造函数"""
self.title = title
self.author = author
self.price = price
self.is_borrowed = False # 默认未借出
print(f"《{title}》已入库")
def info(self):
return f"《{self.title}》作者:{self.author},价格:¥{self.price}"
# 创建对象时自动调用 __init__
book1 = Book("Python编程", "张三", 59.9)
book2 = Book("数据结构", "李四", 49.9)
print(book1.info())
print(book2.info())
5.2 带默认参数的构造函数
class User:
def __init__(self, username, password, is_vip=False, level=1):
self.username = username
self.password = password
self.is_vip = is_vip
self.level = level
def show(self):
vip_status = "VIP" if self.is_vip else "普通用户"
return f"{self.username} - {vip_status} - 等级{self.level}"
# 使用默认参数
user1 = User("alice", "123456")
print(user1.show()) # alice - 普通用户 - 等级1
# 覆盖默认参数
user2 = User("bob", "abc123", is_vip=True, level=5)
print(user2.show()) # bob - VIP - 等级5
5.3 析构函数 del
析构函数在对象被销毁时自动调用,用于清理资源。
class FileHandler:
def __init__(self, filename):
self.filename = filename
self.file = open(filename, 'w')
print(f"打开文件:{filename}")
def write(self, content):
self.file.write(content)
def __del__(self):
"""析构函数:对象销毁时自动调用"""
self.file.close()
print(f"关闭文件:{self.filename}")
# 使用
handler = FileHandler("test.txt")
handler.write("Hello, World!")
# 当 handler 不再被引用时,__del__ 自动调用
del handler # 手动删除对象
注意:Python 有垃圾回收机制,通常不需要手动管理内存,__del__ 主要用于释放外部资源(如文件、网络连接等)。
六、继承
6.1 什么是继承
继承允许一个类(子类)继承另一个类(父类)的属性和方法,实现代码复用。
# 父类(基类)
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
return f"{self.name}正在吃东西"
def sleep(self):
return f"{self.name}正在睡觉"
# 子类(派生类)
class Dog(Animal):
def bark(self):
return f"{self.name}:汪汪!"
class Cat(Animal):
def meow(self):
return f"{self.name}:喵喵!"
# 使用
dog = Dog("旺财", 3)
cat = Cat("咪咪", 2)
# 继承父类的方法
print(dog.eat()) # 旺财正在吃东西
print(cat.sleep()) # 咪咪正在睡觉
# 子类自己的方法
print(dog.bark()) # 旺财:汪汪!
print(cat.meow()) # 咪咪:喵喵!
6.2 方法重写(Override)
子类可以重写父类的方法,提供自己的实现。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "动物发出声音"
class Dog(Animal):
def speak(self):
# 重写父类方法
return f"{self.name}:汪汪!"
class Cat(Animal):
def speak(self):
# 重写父类方法
return f"{self.name}:喵喵!"
# 使用
animals = [Dog("旺财"), Cat("咪咪"), Animal("动物")]
for animal in animals:
print(animal.speak())
# 输出:
# 旺财:汪汪!
# 咪咪:喵喵!
# 动物发出声音
6.3 super() 调用父类
使用 super() 可以在子类中调用父类的方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print("Person.__init__ 被调用")
def introduce(self):
return f"我叫{self.name},今年{self.age}岁"
class Student(Person):
def __init__(self, name, age, student_id):
# 调用父类的构造函数
super().__init__(name, age)
self.student_id = student_id
print("Student.__init__ 被调用")
def introduce(self):
# 调用父类的方法并扩展
base = super().introduce()
return f"{base},学号:{self.student_id}"
s = Student("张三", 20, "2024001")
print(s.introduce())
# 输出:
# Person.__init__ 被调用
# Student.__init__ 被调用
# 我叫张三,今年20岁,学号:2024001
6.4 多重继承
Python 支持一个类继承多个父类。
class Flyable:
"""可飞行"""
def fly(self):
return "我能飞!"
class Swimmable:
"""可游泳"""
def swim(self):
return "我能游泳!"
class Duck(Flyable, Swimmable):
"""鸭子:既能飞又能游泳"""
def quack(self):
return "嘎嘎!"
duck = Duck()
print(duck.fly()) # 我能飞!
print(duck.swim()) # 我能游泳!
print(duck.quack()) # 嘎嘎!
方法解析顺序(MRO):
print(Duck.__mro__)
# (<class 'Duck'>, <class 'Flyable'>, <class 'Swimmable'>, <class 'object'>)
七、多态
7.1 什么是多态
多态(Polymorphism) 是指同一操作作用于不同对象产生不同的结果。
class Animal:
def speak(self):
raise NotImplementedError("子类必须实现此方法")
class Dog(Animal):
def speak(self):
return "汪汪!"
class Cat(Animal):
def speak(self):
return "喵喵!"
class Cow(Animal):
def speak(self):
return "哞哞!"
# 多态:同一个函数,不同对象产生不同结果
def animal_sound(animal):
print(animal.speak())
# 使用
dog = Dog()
cat = Cat()
cow = Cow()
animal_sound(dog) # 汪汪!
animal_sound(cat) # 喵喵!
animal_sound(cow) # 哞哞!
7.2 鸭子类型
Python 是动态语言,不强制要求类型继承,只要对象有相应的方法就可以使用。
class Dog:
def speak(self):
return "汪汪!"
class Car:
def speak(self):
return "嘀嘀!"
class Person:
def speak(self):
return "你好!"
# 只要对象有 speak 方法,就可以调用
def make_sound(obj):
if hasattr(obj, 'speak'):
print(obj.speak())
else:
print("这个对象不会发声")
make_sound(Dog()) # 汪汪!
make_sound(Car()) # 嘀嘀!
make_sound(Person()) # 你好!
八、封装与访问控制
8.1 公有与私有
Python 通过命名约定实现访问控制:
| 类型 | 命名规则 | 访问权限 |
|---|---|---|
| 公有 | name |
任何地方都可以访问 |
| 保护 | _name |
约定:类内部和子类可以访问 |
| 私有 | __name |
只能在类内部访问(名称改写) |
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner # 公有属性
self._account_type = "储蓄" # 保护属性
self.__balance = balance # 私有属性(外部无法直接访问)
# 公有方法
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return f"存入 ¥{amount},当前余额:¥{self.__balance}"
return "存入金额必须大于0"
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return f"取出 ¥{amount},当前余额:¥{self.__balance}"
return "余额不足或金额无效"
def get_balance(self):
"""获取余额(getter)"""
return self.__balance
# 使用
account = BankAccount("张三", 1000)
# 访问公有属性
print(account.owner) # 张三
# 访问保护属性(可以访问,但不推荐)
print(account._account_type) # 储蓄
# 访问私有属性(会报错)
# print(account.__balance) # AttributeError
# 通过方法访问私有属性
print(account.get_balance()) # 1000
print(account.deposit(500)) # 存入 ¥500,当前余额:¥1500
print(account.withdraw(200)) # 取出 ¥200,当前余额:¥1300
8.2 名称改写机制
Python 对私有属性进行名称改写(Name Mangling):
class MyClass:
def __init__(self):
self.__private = "私有属性"
obj = MyClass()
# 直接访问会报错
# print(obj.__private) # AttributeError
# 实际上可以通过改写后的名称访问(不推荐)
print(obj._MyClass__private) # 私有属性
九、属性装饰器
9.1 @property 装饰器
使用 @property 可以将方法变成属性一样访问。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""获取半径(getter)"""
return self._radius
@radius.setter
def radius(self, value):
"""设置半径(setter)"""
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@property
def area(self):
"""计算面积(只读属性)"""
return 3.14159 * self._radius ** 2
@property
def circumference(self):
"""计算周长(只读属性)"""
return 2 * 3.14159 * self._radius
# 使用
c = Circle(5)
# 像访问属性一样调用方法
print(c.radius) # 5
print(c.area) # 78.53975
print(c.circumference) # 31.4159
# 设置属性(自动调用 setter)
c.radius = 10
print(c.area) # 314.159
# 设置无效值会报错
# c.radius = -5 # ValueError: 半径不能为负数
# 只读属性不能设置
# c.area = 100 # AttributeError: can't set attribute
9.2 完整示例:温度转换
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
"""摄氏度"""
return self._celsius
@celsius.setter
def celsius(self, value):
self._celsius = value
@property
def fahrenheit(self):
"""华氏度(只读)"""
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
"""设置华氏度,自动转换为摄氏度"""
self._celsius = (value - 32) * 5/9
@property
def kelvin(self):
"""开尔文(只读)"""
return self._celsius + 273.15
# 使用
temp = Temperature(25)
print(f"摄氏度:{temp.celsius}°C") # 25°C
print(f"华氏度:{temp.fahrenheit}°F") # 77.0°F
print(f"开尔文:{temp.kelvin}K") # 298.15K
# 设置华氏度
temp.fahrenheit = 100
print(f"摄氏度:{temp.celsius}°C") # 37.777...°C
十、魔术方法(特殊方法)
10.1 什么是魔术方法
魔术方法是以双下划线开头和结尾的特殊方法,用于实现对象的特定行为。
10.2 字符串表示方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""用户友好的字符串表示(print 调用)"""
return f"Person(name='{self.name}', age={self.age})"
def __repr__(self):
"""开发者的字符串表示(交互式环境调用)"""
return f"Person('{self.name}', {self.age})"
p = Person("张三", 25)
print(str(p)) # Person(name='张三', age=25)
print(repr(p)) # Person('张三', 25)
10.3 比较方法
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __eq__(self, other):
"""等于 =="""
return self.score == other.score
def __lt__(self, other):
"""小于 <"""
return self.score < other.score
def __le__(self, other):
"""小于等于 <="""
return self.score <= other.score
def __gt__(self, other):
"""大于 >"""
return self.score > other.score
def __ge__(self, other):
"""大于等于 >="""
return self.score >= other.score
def __str__(self):
return f"{self.name}: {self.score}"
# 使用
s1 = Student("张三", 85)
s2 = Student("李四", 90)
s3 = Student("王五", 85)
print(s1 < s2) # True
print(s1 == s3) # True
print(s2 > s1) # True
# 排序
students = [s1, s2, s3]
students.sort()
for s in students:
print(s)
# 张三: 85
# 王五: 85
# 李四: 90
10.4 算术运算符
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 __sub__(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 __str__(self):
return f"Vector({self.x}, {self.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(v2 - v1) # Vector(2, 2)
print(v1 * 3) # Vector(3, 6)
10.5 容器类方法
class MyList:
"""自定义列表"""
def __init__(self):
self._data = []
def __len__(self):
"""长度 len()"""
return len(self._data)
def __getitem__(self, index):
"""获取元素 []"""
return self._data[index]
def __setitem__(self, index, value):
"""设置元素 [] = """
self._data[index] = value
def __contains__(self, item):
"""包含 in"""
return item in self._data
def append(self, item):
self._data.append(item)
def __iter__(self):
"""迭代"""
return iter(self._data)
# 使用
my_list = MyList()
my_list.append(1)
my_list.append(2)
my_list.append(3)
print(len(my_list)) # 3
print(my_list[0]) # 1
my_list[0] = 100
print(my_list[0]) # 100
print(2 in my_list) # True
for item in my_list:
print(item)
10.6 常用魔术方法速查
| 方法 | 用途 | 示例 |
|---|---|---|
__init__ |
构造函数 | obj = Class() |
__del__ |
析构函数 | del obj |
__str__ |
字符串表示 | str(obj), print(obj) |
__repr__ |
开发者字符串 | repr(obj) |
__eq__ |
等于 | obj1 == obj2 |
__lt__ |
小于 | obj1 < obj2 |
__add__ |
加法 | obj1 + obj2 |
__sub__ |
减法 | obj1 - obj2 |
__len__ |
长度 | len(obj) |
__getitem__ |
索引访问 | obj[key] |
__setitem__ |
索引赋值 | obj[key] = value |
__contains__ |
包含 | item in obj |
__iter__ |
迭代 | for item in obj |
__call__ |
对象调用 | obj() |
十一、面向对象设计原则
11.1 单一职责原则(SRP)
一个类应该只有一个引起它变化的原因。
# ❌ 不好的设计:一个类做太多事
class UserManager:
def create_user(self): pass
def delete_user(self): pass
def send_email(self): pass # 不应该在这里
def generate_report(self): pass # 不应该在这里
# ✅ 好的设计:职责分离
class UserService:
def create_user(self): pass
def delete_user(self): pass
class EmailService:
def send_email(self): pass
class ReportService:
def generate_report(self): pass
11.2 开闭原则(OCP)
对扩展开放,对修改关闭。
# ❌ 不好的设计:每次新增形状都要修改
class AreaCalculator:
def calculate(self, shape):
if shape.type == "circle":
return 3.14 * shape.radius ** 2
elif shape.type == "rectangle":
return shape.width * shape.height
# ✅ 好的设计:通过继承扩展
class Shape:
def area(self):
raise NotImplementedError
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# 新增形状不需要修改现有代码
class Triangle(Shape):
def area(self):
return 0.5 * self.base * self.height
11.3 里氏替换原则(LSP)
子类应该能够替换父类而不影响程序正确性。
class Bird:
def fly(self):
return "I can fly!"
# ❌ 不好的设计:企鹅不能飞
class Penguin(Bird):
def fly(self):
raise Exception("Penguins can't fly!")
# ✅ 好的设计:合理划分继承层次
class Bird:
def move(self):
return "I can move!"
class FlyingBird(Bird):
def fly(self):
return "I can fly!"
class Penguin(Bird):
def swim(self):
return "I can swim!"
11.4 依赖倒置原则(DIP)
高层模块不应该依赖低层模块,两者都应该依赖抽象。
from abc import ABC, abstractmethod
# 抽象接口
class Database(ABC):
@abstractmethod
def save(self, data): pass
# 具体实现
class MySQLDatabase(Database):
def save(self, data):
print(f"Saving to MySQL: {data}")
class MongoDBDatabase(Database):
def save(self, data):
print(f"Saving to MongoDB: {data}")
# 高层模块依赖抽象,不依赖具体实现
class UserService:
def __init__(self, database: Database):
self.db = database
def save_user(self, user):
self.db.save(user)
# 可以轻松切换数据库
service1 = UserService(MySQLDatabase())
service2 = UserService(MongoDBDatabase())
十二、综合示例
12.1 图书管理系统
from datetime import datetime, timedelta
class Book:
"""图书类"""
def __init__(self, isbn, title, author, total_copies=1):
self.isbn = isbn
self.title = title
self.author = author
self.total_copies = total_copies
self.available_copies = total_copies
def __str__(self):
return f"《{self.title}》作者:{self.author}"
def is_available(self):
return self.available_copies > 0
def borrow(self):
if self.is_available():
self.available_copies -= 1
return True
return False
def return_book(self):
if self.available_copies < self.total_copies:
self.available_copies += 1
return True
return False
class Member:
"""会员类"""
def __init__(self, member_id, name):
self.member_id = member_id
self.name = name
self.borrowed_books = []
self.max_books = 3
def can_borrow(self):
return len(self.borrowed_books) < self.max_books
def borrow_book(self, book):
if not self.can_borrow():
return False, "已达到最大借书数量"
if not book.is_available():
return False, "该书暂无库存"
book.borrow()
due_date = datetime.now() + timedelta(days=30)
self.borrowed_books.append({
'book': book,
'borrow_date': datetime.now(),
'due_date': due_date
})
return True, f"借阅成功,请于 {due_date.strftime('%Y-%m-%d')} 前归还"
def return_book(self, book):
for record in self.borrowed_books:
if record['book'] == book:
book.return_book()
self.borrowed_books.remove(record)
return True, "归还成功"
return False, "您没有借阅此书"
class Library:
"""图书馆类"""
def __init__(self, name):
self.name = name
self.books = {}
self.members = {}
def add_book(self, book):
self.books[book.isbn] = book
print(f"入库:{book}")
def register_member(self, member):
self.members[member.member_id] = member
print(f"注册会员:{member.name}")
def find_book(self, isbn):
return self.books.get(isbn)
def find_member(self, member_id):
return self.members.get(member_id)
def list_available_books(self):
available = [book for book in self.books.values() if book.is_available()]
print(f"\n可借阅图书(共{len(available)}本):")
for book in available:
print(f" {book}(库存:{book.available_copies})")
# 使用示例
library = Library("市立图书馆")
# 添加图书
library.add_book(Book("978-7-111-1", "Python编程", "张三", 3))
library.add_book(Book("978-7-111-2", "数据结构", "李四", 2))
library.add_book(Book("978-7-111-3", "算法导论", "王五", 1))
# 注册会员
library.register_member(Member("M001", "小明"))
library.register_member(Member("M002", "小红"))
# 查看可借阅图书
library.list_available_books()
# 借书
member = library.find_member("M001")
book = library.find_book("978-7-111-1")
success, message = member.borrow_book(book)
print(f"\n{member.name} 借书:{message}")
# 再次查看
library.list_available_books()
十三、速查表
类定义速查
class MyClass:
# 类属性
class_attr = "共享"
def __init__(self, param):
# 实例属性
self.instance_attr = param
# 实例方法
def instance_method(self):
return self.instance_attr
@classmethod
def class_method(cls):
return cls.class_attr
@staticmethod
def static_method():
return "独立功能"
@property
def prop(self):
return self._value
@prop.setter
def prop(self, value):
self._value = value
继承速查
# 单继承
class Child(Parent):
def __init__(self, param):
super().__init__(param)
# 多继承
class Child(Parent1, Parent2):
pass
# 方法重写
class Child(Parent):
def method(self):
# 调用父类方法
result = super().method()
# 添加自己的逻辑
return result
访问控制速查
| 类型 | 命名 | 访问方式 |
|---|---|---|
| 公有 | name |
obj.name |
| 保护 | _name |
obj._name(约定) |
| 私有 | __name |
obj._Class__name(改写后) |
魔术方法速查
| 类别 | 方法 | 说明 |
|---|---|---|
| 构造 | __init__ |
构造函数 |
| 析构 | __del__ |
析构函数 |
| 字符串 | __str__ |
用户友好字符串 |
| 字符串 | __repr__ |
开发者字符串 |
| 比较 | __eq__, __lt__ |
等于、小于 |
| 算术 | __add__, __sub__ |
加减法 |
| 容器 | __len__, __getitem__ |
长度、索引 |
| 迭代 | __iter__, __next__ |
迭代器 |
| 调用 | __call__ |
对象可调用 |
更多推荐

所有评论(0)