Python教程42:综合项目-图书管理系统
“纸上得来终觉浅,绝知此事要躬行。”
经过第四部分12课的学习,我们掌握了OOP的核心概念。今天通过一个完整的图书管理系统,综合运用所学知识。
1. 项目需求
功能需求
基本功能:
- 图书管理:添加、删除、搜索、借阅、归还
- 用户管理:注册、借阅记录
- 分类管理:按类别组织图书
进阶功能:
- 数据持久化(JSON)
- 借阅期限和逾期管理
- 统计报表
技术要求
- 使用类和对象
- 继承和多态
- 抽象基类
- 属性管理(@property)
- 异常处理
- 文件操作
2. 系统设计
类设计
Library System
├── Book(图书基类)
│ ├── PhysicalBook(实体书)
│ └── EBook(电子书)
├── User(用户类)
├── Library(图书馆类)
├── BorrowRecord(借阅记录)
└── Storage(存储类)
3. 核心实现
Book基类
1from abc import ABC, abstractmethod
2from datetime import datetime
3
4class Book(ABC):
5 """图书抽象基类"""
6
7 def __init__(self, isbn, title, author, category):
8 self.isbn = isbn
9 self.title = title
10 self.author = author
11 self.category = category
12 self.is_borrowed = False
13
14 @abstractmethod
15 def get_type(self):
16 """获取图书类型"""
17 pass
18
19 def to_dict(self):
20 """序列化"""
21 return {
22 'isbn': self.isbn,
23 'title': self.title,
24 'author': self.author,
25 'category': self.category,
26 'is_borrowed': self.is_borrowed,
27 'type': self.get_type()
28 }
29
30 def __str__(self):
31 status = "已借出" if self.is_borrowed else "可借阅"
32 return f"{self.title} by {self.author} ({status})"
33
34class PhysicalBook(Book):
35 """实体书"""
36 def __init__(self, isbn, title, author, category, location):
37 super().__init__(isbn, title, author, category)
38 self.location = location # 书架位置
39
40 def get_type(self):
41 return "physical"
42
43 def to_dict(self):
44 data = super().to_dict()
45 data['location'] = self.location
46 return data
47
48class EBook(Book):
49 """电子书"""
50 def __init__(self, isbn, title, author, category, file_size):
51 super().__init__(isbn, title, author, category)
52 self.file_size = file_size # 文件大小(MB)
53
54 def get_type(self):
55 return "ebook"
56
57 def to_dict(self):
58 data = super().to_dict()
59 data['file_size'] = self.file_size
60 return data
User类
1class User:
2 """用户类"""
3
4 def __init__(self, user_id, name, email):
5 self.user_id = user_id
6 self.name = name
7 self.email = email
8 self.borrowed_books = [] # ISBN列表
9
10 def can_borrow(self, max_books=5):
11 """检查是否可以借阅"""
12 return len(self.borrowed_books) < max_books
13
14 def borrow_book(self, isbn):
15 """借阅图书"""
16 if isbn not in self.borrowed_books:
17 self.borrowed_books.append(isbn)
18
19 def return_book(self, isbn):
20 """归还图书"""
21 if isbn in self.borrowed_books:
22 self.borrowed_books.remove(isbn)
23
24 def to_dict(self):
25 return {
26 'user_id': self.user_id,
27 'name': self.name,
28 'email': self.email,
29 'borrowed_books': self.borrowed_books
30 }
31
32 def __str__(self):
33 return f"User({self.name}, 已借{len(self.borrowed_books)}本)"
BorrowRecord类
1class BorrowRecord:
2 """借阅记录"""
3
4 def __init__(self, user_id, isbn, borrow_date=None):
5 self.user_id = user_id
6 self.isbn = isbn
7 self.borrow_date = borrow_date or datetime.now()
8 self.return_date = None
9 self.due_date = self.borrow_date + timedelta(days=30)
10
11 @property
12 def is_overdue(self):
13 """是否逾期"""
14 if self.return_date:
15 return False
16 return datetime.now() > self.due_date
17
18 def mark_returned(self):
19 """标记为已归还"""
20 self.return_date = datetime.now()
21
22 def to_dict(self):
23 return {
24 'user_id': self.user_id,
25 'isbn': self.isbn,
26 'borrow_date': self.borrow_date.isoformat(),
27 'due_date': self.due_date.isoformat(),
28 'return_date': self.return_date.isoformat() if self.return_date else None
29 }
Library类
1class Library:
2 """图书馆类"""
3
4 def __init__(self, name):
5 self.name = name
6 self.books = {} # ISBN -> Book
7 self.users = {} # user_id -> User
8 self.records = [] # BorrowRecord列表
9
10 def add_book(self, book):
11 """添加图书"""
12 if book.isbn in self.books:
13 raise ValueError(f"图书{book.isbn}已存在")
14 self.books[book.isbn] = book
15
16 def remove_book(self, isbn):
17 """删除图书"""
18 if isbn not in self.books:
19 raise ValueError(f"图书{isbn}不存在")
20 if self.books[isbn].is_borrowed:
21 raise ValueError("图书已借出,无法删除")
22 del self.books[isbn]
23
24 def register_user(self, user):
25 """注册用户"""
26 if user.user_id in self.users:
27 raise ValueError(f"用户{user.user_id}已存在")
28 self.users[user.user_id] = user
29
30 def borrow_book(self, user_id, isbn):
31 """借阅图书"""
32 # 验证
33 if user_id not in self.users:
34 raise ValueError("用户不存在")
35 if isbn not in self.books:
36 raise ValueError("图书不存在")
37
38 user = self.users[user_id]
39 book = self.books[isbn]
40
41 if book.is_borrowed:
42 raise ValueError("图书已被借出")
43 if not user.can_borrow():
44 raise ValueError("借阅数量已达上限")
45
46 # 借阅
47 book.is_borrowed = True
48 user.borrow_book(isbn)
49 record = BorrowRecord(user_id, isbn)
50 self.records.append(record)
51
52 return f"{user.name}成功借阅《{book.title}》"
53
54 def return_book(self, user_id, isbn):
55 """归还图书"""
56 if user_id not in self.users:
57 raise ValueError("用户不存在")
58 if isbn not in self.books:
59 raise ValueError("图书不存在")
60
61 user = self.users[user_id]
62 book = self.books[isbn]
63
64 if not book.is_borrowed:
65 raise ValueError("图书未被借出")
66
67 # 归还
68 book.is_borrowed = False
69 user.return_book(isbn)
70
71 # 更新记录
72 for record in reversed(self.records):
73 if (record.user_id == user_id and
74 record.isbn == isbn and
75 not record.return_date):
76 record.mark_returned()
77 break
78
79 return f"{user.name}成功归还《{book.title}》"
80
81 def search_books(self, keyword):
82 """搜索图书"""
83 results = []
84 keyword = keyword.lower()
85 for book in self.books.values():
86 if (keyword in book.title.lower() or
87 keyword in book.author.lower() or
88 keyword in book.category.lower()):
89 results.append(book)
90 return results
91
92 def get_statistics(self):
93 """获取统计信息"""
94 total_books = len(self.books)
95 borrowed = sum(1 for book in self.books.values() if book.is_borrowed)
96 overdue = sum(1 for record in self.records if record.is_overdue)
97
98 return {
99 'total_books': total_books,
100 'available': total_books - borrowed,
101 'borrowed': borrowed,
102 'total_users': len(self.users),
103 'overdue_records': overdue
104 }
4. 使用示例
1# 创建图书馆
2library = Library("市图书馆")
3
4# 添加图书
5book1 = PhysicalBook("978-1", "Python编程", "作者A", "编程", "A-101")
6book2 = EBook("978-2", "数据结构", "作者B", "编程", 15.5)
7library.add_book(book1)
8library.add_book(book2)
9
10# 注册用户
11user = User("U001", "张三", "zhang@example.com")
12library.register_user(user)
13
14# 借阅流程
15print(library.borrow_book("U001", "978-1"))
16print(library.borrow_book("U001", "978-2"))
17
18# 搜索
19results = library.search_books("Python")
20for book in results:
21 print(book)
22
23# 统计
24stats = library.get_statistics()
25print(f"总藏书:{stats['total_books']}")
26print(f"可借阅:{stats['available']}")
27print(f"已借出:{stats['borrowed']}")
28
29# 归还
30print(library.return_book("U001", "978-1"))
5. 知识点回顾
这个项目运用了:
- 类和对象:Book、User、Library等
- 继承:PhysicalBook、EBook继承Book
- 抽象基类:Book使用ABC
- 多态:不同类型的书有不同实现
- 属性:@property装饰器
- 异常处理:验证和错误处理
- 封装:数据和方法组织
- 组合:Library包含Books和Users
6. 小结
通过图书管理系统项目,我们综合运用了OOP的核心概念。第四部分(面向对象编程)到此结束。
已学内容:
- 类与对象、继承、多态
- 魔术方法、类方法、静态方法
- 属性、描述符
- 抽象基类、多重继承
- 元类、设计模式
- 最佳实践
面向对象是Python编程的重要范式,掌握它能显著提升代码组织能力。
练习题:
- 为系统添加数据持久化(JSON文件)
- 实现图书预约功能
- 添加GUI界面(tkinter)
本文代码示例:
关注公众号:极客老墨
更多 AI 应用开发、工程实践和效率工具分享,欢迎扫码关注。
