深入面向对象编程
1. 特殊方法(Magic Methods)
特殊方法以双下划线开头和结尾,用于自定义类的行为。
-
__repr__
:开发者用的对象表示,通常用于调试。 -
__eq__
:定义对象相等性(==
)。 -
__len__
:返回对象的“长度”。 -
示例:
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"《{self.title}》 by {self.author}"
def __repr__(self):
return f"Book(title='{self.title}', author='{self.author}')"
def __eq__(self, other):
if isinstance(other, Book):
return self.title == other.title and self.author == other.author
return False
book1 = Book("Python入门", "张三")
book2 = Book("Python入门", "张三")
print(book1) # 输出:《Python入门》 by 张三
print(repr(book1)) # 输出:Book(title='Python入门', author='张三')
print(book1 == book2) # 输出:True
2. 类装饰器与属性管理
- property 装饰器:控制属性访问,提供 getter 和 setter。
- 示例:
class Book:
def __init__(self, title, author):
self._title = title
self._author = author
@property
def title(self):
return self._title
@title.setter
def title(self, value):
if not value:
raise ValueError("书名不能为空!")
self._title = value
book = Book("Python入门", "张三")
print(book.title) # 输出:Python入门
book.title = "新书名"
print(book.title) # 输出:新书名
# book.title = "" # 抛出 ValueError: 书名不能为空!
3. 类的静态方法和类方法
@staticmethod
:不需要访问实例或类的函数。@classmethod
:接收类本身(cls
)作为参数。- 示例:
class Library:
total_books = 0
@staticmethod
def get_instructions():
return "欢迎使用图书管理系统!"
@classmethod
def update_total(cls, count):
cls.total_books += count
print(Library.get_instructions()) # 输出:欢迎使用图书管理系统!
Library.update_total(5)
print(Library.total_books) # 输出:5
改进实践:增强图书管理系统
我们将之前的图书管理系统升级,加入特殊方法、属性管理和文件存储功能。
代码实现
class Book:
def __init__(self, title, author):
self._title = title
self._author = author
@property
def title(self):
return self._title
@title.setter
def title(self, value):
if not value:
raise ValueError("书名不能为空!")
self._title = value
def __str__(self):
return f"《{self.title}》 by {self._author}"
def __eq__(self, other):
if isinstance(other, Book):
return self.title == other.title and self._author == other._author
return False
class Library:
def __init__(self, filename="library.txt"):
self.books = []
self.filename = filename
self.load_books() # 启动时加载文件
def add_book(self, title, author):
book = Book(title, author)
if book not in self.books: # 检查重复
self.books.append(book)
print(f"已添加 {book}")
self.save_books()
else:
print("该书籍已存在!")
def view_books(self):
if not self.books:
print("图书馆暂无书籍!")
else:
print("\n图书馆书籍:")
for i, book in enumerate(self.books, 1):
print(f"{i}. {book}")
def remove_book(self, title):
for book in self.books[:]:
if book.title == title:
self.books.remove(book)
print(f"已删除 《{title}》")
self.save_books()
return
print("未找到该书籍!")
def save_books(self):
"""保存书籍到文件"""
with open(self.filename, 'w', encoding='utf-8') as file:
for book in self.books:
file.write(f"{book.title},{book._author}\n")
def load_books(self):
"""从文件加载书籍"""
try:
with open(self.filename, 'r', encoding='utf-8') as file:
for line in file:
title, author = line.strip().split(',')
self.books.append(Book(title, author))
except FileNotFoundError:
pass # 文件不存在时跳过
def main():
library = Library()
while True:
print("\n=== 图书管理系统 ===")
print("1. 添加书籍")
print("2. 查看所有书籍")
print("3. 删除书籍")
print("4. 退出")
choice = input("请选择操作(1-4):")
if choice == "1":
title = input("请输入书名:")
author = input("请输入作者:")
try:
library.add_book(title, author)
except ValueError as e:
print(f"错误:{e}")
elif choice == "2":
library.view_books()
elif choice == "3":
title = input("请输入要删除的书名:")
library.remove_book(title)
elif choice == "4":
print("谢谢使用!")
break
else:
print("无效选择,请输入 1-4!")
if __name__ == "__main__":
main()
改进亮点
-
特殊方法:
__eq__
:避免重复添加相同书籍。__str__
:保持美观的输出。
-
属性管理:
- 用
@property
和@setter
控制title
,确保不为空。
- 用
-
文件持久化:
save_books()
:每次操作后保存到library.txt
。load_books()
:启动时从文件加载书籍。
动手实践
- 新建文件
library_manager_v2.py
,复制代码。 - 运行程序,试试:
- 选
1
,添加《Python入门》(张三)。 - 选
1
,再次添加《Python入门》(张三),提示已存在。 - 选
2
,查看书籍。 - 关闭程序,重新运行,书籍依然存在。
- 选
3
,删除《Python入门》。
- 选
- 检查
library.txt
,内容格式如:
Python入门,张三
小挑战
- 搜索功能:添加按书名或作者搜索书籍。
- 借阅状态:给
Book
增加is_borrowed
属性,管理借阅。 - 类方法:统计图书馆的总书籍数。
第4周总结
我们已经深入了 OOP:
- 类、对象、继承、多态。
- 特殊方法(
__str__
、__eq__
等)。 - 属性管理(
@property
)。 - 实践:图书管理系统。